import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
import { execFileSync } from "node:child_process";
import { makeDevice } from "../mobile-behavior/device.ts";
import { runPromise } from "./t3.ts";

const [mode, checkout, home, threadFile, serverPort, metro, session, out] = process.argv.slice(2);
mkdirSync(out!, { recursive: true });
const probe = makeDevice({ agentDevice: "agent-device", targetArgs: ["--session", session!], metro: metro!, deviceName: "" });
const evaluate = (expression: string) => runPromise(probe.evaluate(expression));
const command = (...args: string[]) => execFileSync("agent-device", [...args, "--session", session!], { encoding: "utf8", timeout: 120000 });
const stableScreenshot = async (name: string) => {
 for(let attempt=0;attempt<1;attempt++) {
  command("screenshot", `${out}/${name}-a.png`);
  await new Promise(r=>setTimeout(r,500));
  command("screenshot", `${out}/${name}.png`);
  if(readFileSync(`${out}/${name}-a.png`).equals(readFileSync(`${out}/${name}.png`))) return true;
 }
 return false;
};
const sampleTimers = async (durationMs: number) => {
 const samples=[]; const until=Date.now()+durationMs;
 do { samples.push(await evaluate("__timerRead()")); await new Promise(r=>setTimeout(r,250)); } while(Date.now()<until);
 return samples;
};
const thread = JSON.parse(readFileSync(threadFile!, "utf8"));
const environment = await (await fetch(`http://127.0.0.1:${serverPort}/.well-known/t3/environment`)).json() as { environmentId: string };
if (mode === "inspect") {
 console.log(JSON.stringify(await evaluate("({ shim: typeof __timerRead, sockets: __timerSockets.map(s => ({ state: s.readyState, path: s.url.split('?')[0].split('/').slice(3).join('/') })), state: JSON.parse(__t3Behavior.state()) })")));
} else if (mode === "skew") {
 console.log(JSON.stringify(await evaluate("(() => { globalThis.__timerInitialSocketCount = __timerSockets.length; __timerClockShift=-3600000; for(const s of __timerSockets) if(s.readyState===1 && s.url.includes('/ws')) s.close(); return {shift:__timerClockShift}; })()")));
 let connected=false;
 for(let i=0;i<80;i++) { connected=Boolean(await evaluate("__timerSockets.slice(__timerInitialSocketCount).some(s=>s.readyState===1)")); if(connected) break; await new Promise(r=>setTimeout(r,250)); }
 console.log(JSON.stringify({reconnected:connected}));
 console.log(JSON.stringify(await evaluate(`__t3Behavior.open(${JSON.stringify(`t3code-dev://threads/${environment.environmentId}/${thread.threadId}`)})`)));
} else if (mode === "capture") {
 const observations: Record<string, unknown> = {};
 observations.route = await evaluate("JSON.parse(__t3Behavior.state()).route");
 command("record", "start", `${out}/native.mp4`, "--hide-touches");
 execFileSync(process.execPath, ["apps/server/src/bin.ts", "thread", "send", thread.threadId, "again", "--base-dir", home!], {cwd:checkout,env:{...process.env,T3CODE_PORT:serverPort}, encoding:"utf8"});
 observations.detail = await sampleTimers(8000);
 observations.detailStillStable = await stableScreenshot("detail");
 command("back");
 command("press", "500", "490");
 observations.list = await sampleTimers(8000);
 observations.listStillStable = await stableScreenshot("list");
 observations.after = await sampleTimers(16000);
 writeFileSync(`${out}/observations.json`, JSON.stringify(observations,null,2));
 console.log(command("record", "stop"));
 console.log("Native detail and list recording complete");
} else if (mode === "prepare") {
 execFileSync(process.execPath, ["apps/server/src/bin.ts", "thread", "send", thread.threadId, "again", "--wait", "--base-dir", home!], {cwd:checkout,env:{...process.env,T3CODE_PORT:serverPort}, encoding:"utf8"});
 console.log("Second completed seed turn ready");
} else if (mode === "open") {
 console.log(JSON.stringify(await evaluate(`__t3Behavior.open(${JSON.stringify(`t3code-dev://threads/${environment.environmentId}/${thread.threadId}`)})`)));
}
