import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
import { spawnSync } from 'node:child_process';
import { createReportNormalizer } from './normalize-report.mjs';
const root=process.cwd();
fs.mkdirSync('reports',{recursive:true});
const hash=p=>crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex');
const inputs=['package.json','package-lock.json','public/model.js','tests/scenarios.test.js','vitest.config.js','scripts/capture.mjs','scripts/normalize-report.mjs'];
const sourceHashes=Object.fromEntries(inputs.map(p=>[p,hash(p)]));
const { normalize, cleanString: clean }=createReportNormalizer(root);
const runs={};
for (const variant of ['fixed','broken']) {
  const rawPath='reports/'+variant+'.raw.json';
  if(fs.existsSync(rawPath))fs.unlinkSync(rawPath);
  const args=['node_modules/vitest/vitest.mjs','run','--reporter=json','--outputFile=reports/'+variant+'.raw.json'];
  const result=spawnSync(process.execPath,args,{cwd:root,env:{...process.env,LAB_VARIANT:variant,NO_COLOR:'1'},encoding:'utf8',timeout:60000});
  const expected=variant==='fixed'?0:1;
  if(result.status!==expected) throw new Error(`${variant} expected exit ${expected}, got ${result.status}\n${result.stdout}\n${result.stderr}`);
  const raw=JSON.parse(fs.readFileSync('reports/'+variant+'.raw.json','utf8'));
  const normalized=normalize(raw);
  fs.writeFileSync('reports/'+variant+'.json',JSON.stringify(normalized,null,2)+'\n');
  fs.writeFileSync('reports/'+variant+'.console.txt',clean(result.stdout+'\n'+result.stderr));
  runs[variant]={exitCode:result.status,command:'LAB_VARIANT='+variant+' vitest run --reporter=json',total:raw.numTotalTests,passed:raw.numPassedTests,failed:raw.numFailedTests,success:raw.success,assertions:normalized.testResults.flatMap(r=>r.assertionResults)};
  fs.unlinkSync(rawPath);
}
if(fs.existsSync('reports/coverage-run.raw.json'))fs.unlinkSync('reports/coverage-run.raw.json');
const coverage=spawnSync(process.execPath,['node_modules/vitest/vitest.mjs','run','--coverage','--reporter=json','--outputFile=reports/coverage-run.raw.json'],{cwd:root,env:{...process.env,LAB_VARIANT:'fixed',NO_COLOR:'1'},encoding:'utf8',timeout:60000});
if(coverage.status!==0)throw new Error('Coverage failed\n'+coverage.stdout+'\n'+coverage.stderr);
const summary=JSON.parse(fs.readFileSync('reports/coverage/coverage-summary.json','utf8'));
const coverageRaw=JSON.parse(fs.readFileSync('reports/coverage-run.raw.json','utf8'));
fs.writeFileSync('reports/coverage-run.json',JSON.stringify(normalize(coverageRaw),null,2)+'\n');
fs.unlinkSync('reports/coverage-run.raw.json');
fs.writeFileSync('reports/coverage.console.txt',clean(coverage.stdout+'\n'+coverage.stderr));
const report={schema:1,recordedAt:new Date().toISOString(),runtime:{node:process.version,vitest:JSON.parse(fs.readFileSync('node_modules/vitest/package.json')).version,jsdom:JSON.parse(fs.readFileSync('node_modules/jsdom/package.json')).version,platform:process.platform},mechanism:'Saved output from real Vitest runs. This public page does not run Vitest.',sourceHashes,runs,coverage:summary.total,browser:{status:'not-run',providerPrepared:['preview','playwright'],note:'Browser Mode execution is separate from the JSDOM preflight; do not infer browser geometry or touch from JSDOM.'}};
for(const [p,sha] of Object.entries(sourceHashes))if(hash(p)!==sha)throw new Error('Source changed during capture: '+p);
fs.writeFileSync('public/reports.json',JSON.stringify(report,null,2)+'\n');
fs.writeFileSync('reports/capture.json',JSON.stringify(report,null,2)+'\n');
console.log(JSON.stringify({fixed:runs.fixed.passed+'/'+runs.fixed.total,broken:runs.broken.failed+' intentional failures',coverage:report.coverage,browser:report.browser.status},null,2));
