import { cpSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { execFileSync, spawnSync } from 'node:child_process';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { tmpdir } from 'node:os';

const sourceRoot = dirname(dirname(fileURLToPath(import.meta.url)));
const tempRoot = mkdtempSync(join(tmpdir(), 'vendoo-git-gate-regression-'));
const testRoot = join(tempRoot, 'repo');
mkdirSync(join(testRoot, 'tools'), { recursive: true });
cpSync(join(sourceRoot, 'tools', 'verify-git-safety.mjs'), join(testRoot, 'tools', 'verify-git-safety.mjs'));
writeFileSync(join(testRoot, '.gitignore'), '.env\nnode_modules/\nruntime/\nmodules/\n/Archiv/\n/archive/\n/archives/\noperations/pending-operation.json\nlocal-ai/comfyui/\n.vendoo-install-mode\n', 'utf8');
writeFileSync(join(testRoot, 'package.json'), '{"type":"module"}\n', 'utf8');

try {
  execFileSync('git', ['init'], { cwd: testRoot, stdio: 'ignore' });
  execFileSync('git', ['add', '.gitignore', 'package.json', 'tools/verify-git-safety.mjs'], { cwd: testRoot, stdio: 'ignore' });

  // Entscheidend: Diese Dateien bleiben absichtlich unversioniert.
  const openAiLike = 'sk-' + 'this-is-a-regression-test-secret-1234567890';
  writeFileSync(join(testRoot, '.env.local'), `OPENAI_API_KEY=${openAiLike}\n`, 'utf8');
  const githubLike = 'github_' + 'pat_' + 'abcdefghijklmnopqrstuvwxyz0123456789TEST';
  writeFileSync(join(testRoot, 'untracked-secret.txt'), `${githubLike}\n`, 'utf8');

  const blocked = spawnSync(process.execPath, ['tools/verify-git-safety.mjs'], { cwd: testRoot, encoding: 'utf8' });
  if (blocked.status === 0) throw new Error('Gate hat unversionierte Secret-Dateien nicht blockiert.');
  const report = `${blocked.stdout || ''}\n${blocked.stderr || ''}`;
  if (!report.includes('.env.local') || !report.includes('untracked-secret.txt')) {
    throw new Error(`Gate-Bericht nennt nicht alle unversionierten Treffer:\n${report}`);
  }

  rmSync(join(testRoot, '.env.local'));
  rmSync(join(testRoot, 'untracked-secret.txt'));

  // Installierte Laufzeitmodule dürfen niemals in Git gelangen.
  mkdirSync(join(testRoot, 'modules', 'vendoo.ext-demo'), { recursive: true });
  writeFileSync(join(testRoot, 'modules', 'vendoo.ext-demo', 'package.vmod'), '{"runtime":true}\n', 'utf8');
  const moduleBlocked = spawnSync(process.execPath, ['tools/verify-git-safety.mjs'], { cwd: testRoot, encoding: 'utf8' });
  if (moduleBlocked.status === 0) throw new Error('Gate hat den Laufzeitordner modules/ nicht blockiert.');
  if (!`${moduleBlocked.stdout || ''}\n${moduleBlocked.stderr || ''}`.includes('modules/vendoo.ext-demo/package.vmod')) {
    throw new Error('Gate-Bericht nennt das installierte Laufzeitmodul nicht.');
  }
  rmSync(join(testRoot, 'modules'), { recursive: true, force: true });

  // Historische Übergabeordner dürfen lokal existieren, werden aber weder geprüft noch gepusht.
  mkdirSync(join(testRoot, 'Archiv', 'Vendoo_Alt', 'vendoo'), { recursive: true });
  const archivedSecret = 'sk-' + 'this-archived-test-value-must-be-ignored-1234567890';
  writeFileSync(join(testRoot, 'Archiv', 'Vendoo_Alt', 'vendoo', 'server.mjs'), `OPENAI_API_KEY=${archivedSecret}\n`, 'utf8');

  // Ein Quellmodul namens sessions ist zulässig; nur lokale Top-Level-Laufzeit-Sessions sind verboten.
  mkdirSync(join(testRoot, 'app', 'modules', 'sessions'), { recursive: true });
  writeFileSync(join(testRoot, 'app', 'modules', 'sessions', 'index.mjs'), 'export const sourceModule = true;\n', 'utf8');

  const clean = spawnSync(process.execPath, ['tools/verify-git-safety.mjs'], { cwd: testRoot, encoding: 'utf8' });
  if (clean.status !== 0) throw new Error(`Gate lehnt sauberen Arbeitsbaum ab:\n${clean.stdout}\n${clean.stderr}`);

  console.log('Git-Sicherheitsgate-Regressionstest erfolgreich: unversionierte Secrets und installierte Laufzeitmodule werden blockiert, Archivstände bleiben ausgeschlossen, das Quellmodul app/modules/sessions bleibt zulässig und ein sauberer Arbeitsbaum wird akzeptiert.');
} finally {
  rmSync(tempRoot, { recursive: true, force: true });
}
