import {mkdtemp,writeFile,readFile,mkdir,rm} from 'node:fs/promises';import {tmpdir} from 'node:os';import {join,resolve,dirname} from 'node:path';import {spawnSync} from 'node:child_process';import {createHash} from 'node:crypto';import {runInNewContext} from 'node:vm';import {makeCase} from './cases.mjs';
const cli=resolve('node_modules/@biomejs/biome/bin/biome');
export const sha=text=>createHash('sha256').update(text).digest('hex');
function sanitize(value,root){
 if(typeof value==='string')return value.split(root).join('<fixture>').split(root.replaceAll('\\','/')).join('<fixture>');
 if(Array.isArray(value))return value.map(x=>sanitize(x,root));
 if(value&&typeof value==='object')return Object.fromEntries(Object.entries(value).map(([k,v])=>[sanitize(k,root),sanitize(v,root)]));
 return value;
}
export async function runCase(id,variant){
 const fixture=makeCase(id,variant),directory=await mkdtemp(join(tmpdir(),'aen-biome-'));
 try{
  await writeFile(join(directory,'biome.json'),JSON.stringify(fixture.config,null,2)+'\n');
  for(const[name,content]of Object.entries(fixture.files)){await mkdir(dirname(join(directory,name)),{recursive:true});await writeFile(join(directory,name),content);}
  const exec=args=>{const r=spawnSync(process.execPath,[cli,...args,'--colors=off','--max-diagnostics=100'],{cwd:directory,encoding:'utf8',env:{...process.env,NO_COLOR:'1'},timeout:20000});if(r.error)throw r.error;return{exitCode:r.status,stdout:r.stdout,stderr:r.stderr};};
  const diagnose=()=>{const r=exec(['check','.','--reporter=json']);let report;try{report=JSON.parse(r.stdout);}catch{throw new Error('Missing Biome JSON: '+r.stderr);}return{...r,report};};
  const before=await diagnose();const started=performance.now();const run=exec(fixture.args);const elapsedMs=Math.round(performance.now()-started);const afterFiles={};for(const name of Object.keys(fixture.files))afterFiles[name]=await readFile(join(directory,name),'utf8');const after=await diagnose();
  const result={id,variant,command:'biome '+fixture.args.join(' '),config:fixture.config,beforeFiles:fixture.files,afterFiles,beforeDiagnostics:before.report,afterDiagnostics:after.report,run,elapsedMs,changedFiles:Object.keys(fixture.files).filter(name=>fixture.files[name]!==afterFiles[name]),hashesBefore:Object.fromEntries(Object.entries(fixture.files).map(([k,v])=>[k,sha(v)])),hashesAfter:Object.fromEntries(Object.entries(afterFiles).map(([k,v])=>[k,sha(v)]))};
  result.configurationChanged=(await readFile(join(directory,'biome.json'),'utf8'))!==JSON.stringify(fixture.config,null,2)+'\n';
  if(id==='fix'&&variant!=='safe')result.behavior={input:['1',1],before:runInNewContext(fixture.files['sample.js'].replace('export ','')+';equal("1",1)'),after:runInNewContext(afterFiles['sample.js'].replace('export ','')+';equal("1",1)'),note:'Реальное выполнение собственного короткого примера; произвольный код посетителя не исполняется.'};
  return sanitize(result,directory);
 }finally{await rm(directory,{recursive:true,force:true});}
}
