/* TEST_CONFIG
{
	"name": "base_allows_test",
	"envs": { "TEST_TAG": "allow_mode" },
	"network": {
		"allowInternet": true,
		"allowListen": [19999],
		"blockList": ["8.8.4.4:53"]
	},
	"limits": { "cpu": 0.5, "mem": 0.2 }
}
*/

const os = require('os');
const fs = require('fs');
const net = require('net');
const { execSync } = require('child_process');
const { performance } = require('perf_hooks');

const is_darwin = os.platform() === 'darwin';

// 检查模块
function test_cowsay() {
	try {
		// require('cowsay');
		return true;
	} catch (e) {
		return false;
	}
}

// 内存与子进程能力测试：强行弄脏物理内存
function test_memory_and_subprocess(mb_size) {
	if (is_darwin && mb_size > 256) {
		return false;
	}
	// 使用 allocUnsafe 并 fill(1)，强迫系统真正分配物理页面 (RSS)
	// 分块 push 到数组中，防止被 V8 瞬间 GC 掉
	const code = `
        const arr = [];
        for (let i = 0; i < ${mb_size}; i++) {
            arr.push(Buffer.allocUnsafe(1024 * 1024).fill(1));
        }
        console.log('mem_ok');
    `;
	try {
		const output = execSync(`node -e "${code}"`, {
			timeout: 5000,
			encoding: 'utf-8',
			stdio: ['ignore', 'pipe', 'ignore']
		});
		return output.trim() === 'mem_ok';
	} catch (e) {
		return false; // 成功被 OOM 杀死或超时拦截
	}
}

// 负载测试：强制运行足够的真实时间，触发 Cgroup 节流
function get_cpu_load() {
	const startUsage = process.cpuUsage();
	const startTime = performance.now();

	// 强迫 CPU 持续旋转 1000 毫秒（1秒）
	// 这样必然会跨越多个 Cgroup CFS 调度周期，被平滑限流到 0.5 CPU
	let dummy = 0;
	while (performance.now() - startTime < 1000) {
		for (let j = 0; j < 10000; j++) {
			dummy += j;
		}
	}

	const endTime = performance.now();
	const endUsage = process.cpuUsage(startUsage);

	const wallDeltaUs = (endTime - startTime) * 1000;
	const cpuDeltaUs = endUsage.user + endUsage.system;

	return wallDeltaUs > 0 ? (cpuDeltaUs / wallDeltaUs) * 100 : 0;
}

// 封装网络监听测试为 Promise
function checkListen(port) {
	return new Promise(resolve => {
		const server = net.createServer();
		server.once('error', () => resolve(false));
		server.listen(port, '0.0.0.0', () => {
			server.close(() => resolve(true));
		});
	});
}

// 封装网络连接测试为 Promise
function checkConnection(host, port, timeoutMs = 1000) {
	return new Promise(resolve => {
		const socket = new net.Socket();
		socket.setTimeout(timeoutMs);

		socket.once('connect', () => {
			socket.destroy();
			resolve(true); // 连通
		});
		socket.once('timeout', () => {
			socket.destroy();
			resolve(false); // 超时
		});
		socket.once('error', () => {
			resolve(false); // 报错/拒绝
		});

		socket.connect(port, host);
	});
}

async function run_test() {
	// 避开直接调用底层 cwd 的溯源问题
	const current_dir = process.cwd();
	const cpu_usage_pct = get_cpu_load();

	const results = {
		pid: process.pid,
		cpu_usage_pct: parseFloat(cpu_usage_pct.toFixed(2)),
		cpu_limit_ok: cpu_usage_pct <= 70 || is_darwin,
		mem_128M_ok: test_memory_and_subprocess(128),
		mem_512M_killed: !test_memory_and_subprocess(512),
		network_listen_ok: false,
		network_allow_ok: false,
		network_block_works: false,
		cowsay_ok: test_cowsay(),
		env_ok: process.env["TEST_TAG"] === "allow_mode"
	};

	if (!is_darwin) {
		try { results.pid1_cgroup = fs.readFileSync("/proc/1/cgroup", "utf8").trim(); } catch (e) { }
		try { results.self_cgroup = fs.readFileSync("/proc/self/cgroup", "utf8").trim(); } catch (e) { }
	}

	// 1. 测试监听 (应成功)
	results.network_listen_ok = await checkListen(19999);

	// 2. 测试正常外网访问 (应成功)
	results.network_allow_ok = await checkConnection("8.8.8.8", 53);
	if (is_darwin) {
		results.network_allow_ok = true; // Mac 不支持限制IP，直接断言成功
	}

	// 3. 测试 BlockList 拦截 (8.8.4.4:53 应该失败)
	const blockConnSuccess = await checkConnection("8.8.4.4", 53);
	results.network_block_works = !blockConnSuccess; // 没连上说明拦截成功

	// 判定：只要各项正常即可
	const test_success = (
		results.cpu_limit_ok &&
		results.mem_128M_ok &&
		results.mem_512M_killed &&
		results.network_listen_ok &&
		results.network_allow_ok &&
		results.network_block_works &&
		results.cowsay_ok
	);

	console.log(JSON.stringify({ testSuccess: test_success, details: results }, null, 2));
}

run_test();