#!/usr/bin/env node
/**
 * Story 2.4 — Test infra cleanup
 *
 * Removes test pollution accumulated in `.catalog/test-*` and `.artifacts/`
 * before `npm run test:all` runs. Without this, sequential test runs fail
 * intermittently because:
 *   - `test_openlife_evolution_surface` asserts `.catalog/` clean of test artifacts
 *   - `test_operating_system` is sensitive to stale `.artifacts/execution-board.json`
 *
 * This is a temporary mitigation. The proper fix (story 2.4 v2) is to add
 * OPENLIFE_CATALOG_DIR env override and have tests point at temp dirs.
 * That's a deeper refactor; this cleanup unblocks test:all deterministically NOW.
 *
 * Invoked via npm `pretest:all` hook. Also safe to run manually.
 */
const fs = require('fs');
const path = require('path');
const { execFileSync } = require('child_process');

const cwd = process.cwd();

const CATALOG_TEST_PATTERNS = ['test-', 'void']; // void is auto-created by some tests
const CATALOG_SUBDIRS = ['agents', 'squads', 'skills', 'mcps'];

let removedCount = 0;

// 1. Remove test-* entities from .catalog/{agents,squads,skills,mcps}/
for (const sub of CATALOG_SUBDIRS) {
  const dir = path.join(cwd, '.catalog', sub);
  if (!fs.existsSync(dir)) continue;
  for (const entry of fs.readdirSync(dir)) {
    const isTest = CATALOG_TEST_PATTERNS.some((p) => entry.startsWith(p));
    if (isTest) {
      const target = path.join(dir, entry);
      try {
        fs.rmSync(target, { recursive: true, force: true });
        removedCount++;
      } catch (err) {
        console.warn(`[clean-test-pollution] could not remove ${target}: ${err.message}`);
      }
    }
  }
}

// 2. Clean .artifacts/* while preserving release-hygiene reports.
//
// Root cause of the v1.19 public-hygiene trap: this script used to delete the
// entire `.artifacts/` tree and then restore tracked files with
// `git checkout -- .artifacts/`. That destroyed local hygiene reports under
// `.artifacts/public-hygiene/` and also failed once `.artifacts/**` became
// intentionally untracked via `git rm --cached`.
//
// Keep the test-suite behavior (clear stale runtime artifacts that make tests
// flaky), but preserve the public-hygiene folder and restore a local copy of
// `.artifacts/squad-scores.json` from HEAD when it exists there. The latter is
// important because the file may be staged for removal from Git tracking while
// still intentionally preserved on disk.
const artifactsDir = path.join(cwd, '.artifacts');
const preservedArtifactsDir = path.join(artifactsDir, 'public-hygiene');
const preservedTmpDir = path.join(cwd, '.openlife-test-preserve-public-hygiene');
let preservedHygiene = false;

if (fs.existsSync(artifactsDir)) {
  try {
    if (fs.existsSync(preservedTmpDir)) {
      fs.rmSync(preservedTmpDir, { recursive: true, force: true });
    }
    if (fs.existsSync(preservedArtifactsDir)) {
      fs.renameSync(preservedArtifactsDir, preservedTmpDir);
      preservedHygiene = true;
    }

    fs.rmSync(artifactsDir, { recursive: true, force: true });
    fs.mkdirSync(artifactsDir, { recursive: true });

    if (preservedHygiene) {
      fs.mkdirSync(path.dirname(preservedArtifactsDir), { recursive: true });
      fs.renameSync(preservedTmpDir, preservedArtifactsDir);
    }
  } catch (err) {
    console.warn(`[clean-test-pollution] artifact reset warning: ${err.message}`);
  }

  // Restore any tracked files in .artifacts/ via git. This remains useful on
  // older branches where selected artifacts are still tracked.
  try {
    execFileSync('git', ['checkout', '--', '.artifacts/'], { cwd, stdio: 'pipe' });
  } catch {
    // No tracked files in .artifacts/ — that's fine.
  }

  // Preserve the local disk copy of the legacy squad score artifact even when
  // the index has staged its removal from Git tracking (`git rm --cached`).
  const squadScores = path.join(artifactsDir, 'squad-scores.json');
  if (!fs.existsSync(squadScores)) {
    try {
      const content = execFileSync('git', ['show', 'HEAD:.artifacts/squad-scores.json'], {
        cwd,
        encoding: 'utf8',
        stdio: ['ignore', 'pipe', 'ignore'],
      });
      fs.writeFileSync(squadScores, content);
    } catch {
      // File does not exist in HEAD on this branch — nothing to preserve.
    }
  }
}

console.log(
  `[clean-test-pollution] removed ${removedCount} test-* catalog entries; .artifacts/ reset; public-hygiene preserved=${preservedHygiene}`,
);
