import { chromium } from 'playwright-core';
import { mkdir, writeFile } from 'node:fs/promises';
import { performance } from 'node:perf_hooks';

export async function proveRestarts(input: {url:string;cookies:any[];storage:Record<string,string>;side:string}) {
 const folder=`${process.env.EVIDENCE_DIR ?? '/tmp/attachment-evidence'}/${input.side}-${Date.now()}`;
 await mkdir(folder,{recursive:true});
 const remaining=300000-Date.now()%300000;
 if(remaining<140000) await new Promise(resolve=>setTimeout(resolve,remaining+1500));
 const profile=`${folder}/profile`;
 const samples:any[]=[];
 let freshHeaders:any={};
 let warmUrl='';
 const launch=()=>chromium.launchPersistentContext(profile,{headless:true,viewport:{width:1280,height:800},recordVideo:{dir:`${folder}/video`,size:{width:1280,height:800}}});
 let context=await launch();
 try {
  await context.addCookies(input.cookies);
  const page=context.pages()[0]!;
  await page.addInitScript(storage=>{for(const [key,value] of Object.entries(storage))localStorage.setItem(key,value);performance.setResourceTimingBufferSize(10000)},input.storage);
  await page.goto(input.url);
  await page.waitForFunction(()=>Array.from(document.images).some(i=>i.src.includes('/api/assets/')&&i.complete&&i.naturalWidth>0),{},{timeout:120000});
  const target=await page.locator('img[src*="/api/assets/"]').first().getAttribute('src');
  freshHeaders=await page.evaluate(async url=>{const response=await fetch(url!,{cache:'reload'});await response.arrayBuffer();const payload=JSON.parse(atob(url!.split('/api/assets/')[1]!.split('.')[0]!.replaceAll('-','+').replaceAll('_','/')));const date=Date.parse(response.headers.get('date')!);return {status:response.status,cacheControl:response.headers.get('cache-control'),remainingAtResponseSeconds:Math.floor((payload.expiresAt-date)/1000)};},target);
  warmUrl=await page.locator('img[src*="/api/assets/"]').first().getAttribute('src') ?? '';
 } finally {await context.close();}
 for(let run=0;run<5;run++) {
  context=await launch();
  try {
   const page=context.pages()[0]!;
   await page.addInitScript(()=>performance.setResourceTimingBufferSize(10000));
   const cdp=await context.newCDPSession(page);
   await cdp.send('Network.enable');
   await cdp.send('Network.setCacheDisabled',{cacheDisabled:false});
   await cdp.send('Network.emulateNetworkConditions',{offline:false,latency:120,downloadThroughput:5_000_000/8,uploadThroughput:5_000_000/8});
   const responses:any[]=[];
   cdp.on('Network.responseReceived',event=>{
    if(!event.response.url.includes('/api/assets/'))return;
    const token=event.response.url.split('/api/assets/')[1]?.split('.')[0];
    let expiry=0;try{expiry=JSON.parse(Buffer.from(token??'','base64url').toString()).expiresAt;}catch{}
    responses.push({id:event.requestId,diskCache:!!event.response.fromDiskCache,status:event.response.status,cacheControl:event.response.headers['Cache-Control']??event.response.headers['cache-control'],secondsLeft:Math.floor((expiry-Date.now())/1000),bytes:null});
   });
   cdp.on('Network.loadingFinished',event=>{const r=responses.find(r=>r.id===event.requestId);if(r)r.bytes=event.encodedDataLength;});
   const start=performance.now();
   await page.goto(input.url,{waitUntil:'domcontentloaded'});
   await page.waitForFunction(()=>Array.from(document.images).some(i=>i.src.includes('/api/assets/')&&i.complete&&i.naturalWidth>0),{},{timeout:120000});
   const visibleMs=Math.round(performance.now()-start);
   const current=await page.locator('img[src*="/api/assets/"]').first().getAttribute('src');
   const metrics=await page.evaluate(()=>performance.getEntriesByType('resource').filter(e=>e.name.includes('/api/assets/')).map(e=>({transferSize:(e as PerformanceResourceTiming).transferSize,encodedBodySize:(e as PerformanceResourceTiming).encodedBodySize,durationMs:Math.round(e.duration)})));
   const sample={run:run+1,visibleMs,sameUrl:current===warmUrl,metrics,responses:responses.map(({id,...rest})=>rest)};
   samples.push(sample);
   await writeFile(`${folder}/samples.json`,JSON.stringify({freshHeaders,samples},null,2));
   await page.locator('img[src*="/api/assets/"]').first().click();
   await page.evaluate(sample=>{const p=document.createElement('div');p.style.cssText='position:fixed;bottom:20px;left:20px;right:20px;background:#102030;color:white;padding:20px;font:17px monospace;z-index:99999;white-space:pre-wrap';p.textContent='Observed process restart • persistent browser profile • 5 Mbps / 120 ms\n'+JSON.stringify(sample,null,2);document.body.append(p);},sample);
   await page.screenshot({path:`${folder}/restart-${run+1}.png`});
  } finally {await context.close();}
 }
 const waitForBoundary=300000-Date.now()%300000+1500;
 await new Promise(resolve=>setTimeout(resolve,waitForBoundary));
 context=await launch();
 let boundary:any={};
 try { const page=context.pages()[0]!;await page.addInitScript(()=>performance.setResourceTimingBufferSize(10000));await page.goto(input.url);await page.waitForFunction(()=>Array.from(document.images).some(i=>i.src.includes('/api/assets/')&&i.complete&&i.naturalWidth>0),{},{timeout:120000});
 const current=await page.locator('img[src*="/api/assets/"]').first().getAttribute('src');boundary={urlChanged:current!==warmUrl,metrics:await page.evaluate(()=>performance.getEntriesByType('resource').filter(e=>e.name.includes('/api/assets/')).map(e=>({transferSize:(e as PerformanceResourceTiming).transferSize,encodedBodySize:(e as PerformanceResourceTiming).encodedBodySize})))};
 await page.locator('img[src*="/api/assets/"]').first().click();await page.evaluate(data=>{const p=document.createElement('div');p.style.cssText='position:fixed;bottom:20px;left:20px;right:20px;background:#102030;color:white;padding:20px;font:18px monospace;z-index:99999;white-space:pre-wrap';p.textContent='Observed reopen after crossing a real five-minute boundary\n'+JSON.stringify(data,null,2);document.body.append(p);},boundary);await page.screenshot({path:`${folder}/boundary.png`});
 } finally {await context.close();}
 const sorted=samples.map(s=>s.visibleMs).sort((a,b)=>a-b);
 const summary={side:input.side,conditions:'Chromium persistent disk profile; HTTP caching enabled; 5 Mbps download/upload; 120 ms latency; development web build; 1280x800',imageBytes:samples[0]?.metrics[0]?.encodedBodySize,medianVisibleMs:sorted[2],freshHeaders,boundary,samples};
 await writeFile(`${folder}/measurements.json`,JSON.stringify(summary,null,2));
 return {folder,summary};
}
