import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import test from 'node:test';

const root = new URL('../', import.meta.url);
const patchName = '0031-use-bot-enemy-for-cover-target.patch';
const read = (path) => readFileSync(new URL(path, root), 'utf8');

function patchList(source, variable) {
  const body = source.match(new RegExp(`${variable}=\\(([\\s\\S]*?)\\n\\)`));
  assert.ok(body, `missing ${variable}`);
  return [...body[1].matchAll(/(\d{4}-[^/"']+\.patch)/g)].map((match) => match[1]);
}

test('dedicated bot retreat finds cover from its active enemy', () => {
  const patch = read(`port/native/patches/${patchName}`);

  assert.match(patch, /diff --git a\/src\/mpgame\/bots\/BotAI\.cpp/);
  assert.doesNotMatch(patch, /diff --git a\/src\/game\//);
  assert.match(patch, /\+	idPlayer\* enemy = BotPlayerForIndex\( bs\.enemy \);/);
  assert.match(patch, /\+	if\( aas == NULL \|\| enemy == NULL \)/);
  assert.match(patch, /\+	areaNum = aas->PointReachableAreaNum/);
  assert.match(patch, /\+	target = aas->AreaCenter\(aas->PointAreaNum\(enemy->GetOrigin\(\)\)\);/);
  assert.doesNotMatch(patch, /^\+.*GetLocalPlayer\(\)/m);
});

test('every GameLib release path applies the dedicated bot cover fix before read-only telemetry', () => {
  for (const script of [
    'tools/build-native.sh',
    'tools/build-wasm.sh',
    'tools/stage-source-offer.sh',
  ]) {
    const source = read(script);
    const gameLibPatches = patchList(source, 'GAMELIBS_PATCH_FILES');
    const coverIndex = gameLibPatches.indexOf(patchName);
    const telemetryIndex = gameLibPatches.indexOf('0033-report-bot-navigation-status.patch');
    assert.ok(coverIndex > gameLibPatches.indexOf('0029-release-bot-resources-on-map-change.patch'));
    assert.equal(telemetryIndex, coverIndex + 1, `${script} does not apply telemetry after ${patchName}`);
    assert.ok(!patchList(source, 'OPENQ4_PATCH_FILES').includes(patchName));
  }

  assert.ok(read('tools/native-source-identity.py').includes(`"${patchName}"`));
});
