import test from 'node:test';
import assert from 'node:assert/strict';

import { contentLoader } from './ContentLoader.js';
import { ValidationEngine } from './ValidationEngine.js';

function createFakeEngine(overrides = {}) {
  const fakeVmManager = {
    async getIP() {
      return '10.42.0.41';
    },
    getManagementUser() {
      return 'opsbridge';
    },
    getSshKeyPath() {
      return '~/.ssh/sc_host_key';
    },
    getDistro(vmId) {
      return vmId === 'build_machine' ? 'arch' : 'debian';
    }
  };

  const sshRunner = async ({ command }) => {
    for (const [matcher, result] of overrides) {
      const matched =
        typeof matcher === 'string'
          ? command.includes(matcher)
          : matcher instanceof RegExp
            ? matcher.test(command)
            : typeof matcher === 'function'
              ? matcher(command)
              : false;

      if (matched) {
        return {
          ok: result.ok,
          code: result.code ?? (result.ok ? 0 : 1),
          stdout: result.stdout ?? '',
          stderr: result.stderr ?? ''
        };
      }
    }

    return { ok: false, code: 1, stdout: '', stderr: `unmatched:${command}` };
  };

  return new ValidationEngine({
    vmManager: fakeVmManager,
    sshRunner
  });
}

test('ValidationEngine selects permissive Q001 branch when owner matches but modes do not', async () => {
  process.env.CONTENT_DIR = '../content';
  await contentLoader.load();

  const engine = createFakeEngine(new Map([
    [(command) => command.includes('test -e') && command.includes('/home/player/.ssh/authorized_keys'), { ok: true, stdout: '' }],
    [(command) => command.includes('stat -c %a') && command.includes('/home/player/.ssh/authorized_keys'), { ok: true, stdout: '644\n' }],
    [(command) => command.includes('stat -c %a') && command.includes('/home/player/.ssh') && !command.includes('authorized_keys'), { ok: true, stdout: '755\n' }],
    [(command) => command.includes('stat -c %U:%G') && command.includes('/home/player/.ssh/authorized_keys'), { ok: true, stdout: 'player:player\n' }]
  ]));

  const quest = contentLoader.get('quests', 'Q001');
  const result = await engine.resolveBranch(quest);

  assert.equal(result.branch?.id, 'permissive-setup');
});

test('ValidationEngine selects highest-priority passing branch for Q002', async () => {
  process.env.CONTENT_DIR = '../content';
  await contentLoader.load();

  const engine = createFakeEngine(new Map([
    [(command) => command.includes('systemctl is-active') && command.includes('nginx'), { ok: true, stdout: 'active\n' }],
    [(command) => command.includes('systemctl is-enabled') && command.includes('nginx'), { ok: true, stdout: 'enabled\n' }],
    [(command) => command.includes('ss -ltn') && command.includes('80'), { ok: true, stdout: '' }],
    [(command) => command.includes('grep -qF') && command.includes('listen 80;') && command.includes('axiomworks.conf'), { ok: true, stdout: '' }]
  ]));

  const quest = contentLoader.get('quests', 'Q002');
  const result = await engine.resolveBranch(quest);

  assert.equal(result.branch?.id, 'config-fixed-enabled');
});
