import { readFileSync, writeFileSync } from 'node:fs';
import { expect } from 'e2e';
import { APP_DIR } from '../e2e.config.ts';
import { test, WEB } from './t3.ts';

test('Agent-created children inherit default mode with legacy plan disabled', WEB, async ({t3, app, screen, browser}) => {
  const replayPath = APP_DIR + '/apps/server/scripts/dev-replay-agent.ts';
  const original = readFileSync(replayPath,'utf8');
  const injection = "        const promptText = JSON.stringify(params.prompt ?? []);\n        if (promptText.includes('PROVE_CHILD_MODES')) {\n          let sid = '';\n          let seq = 0;\n          const endpoint = process.env.T3_ACP_MCP_ENDPOINT!;\n          const auth = process.env.T3_ACP_MCP_AUTHORIZATION!;\n          const rpc = async (method: string, p: unknown) => {\n            const r = await fetch(endpoint, {method:'POST',headers:{'content-type':'application/json',accept:'application/json, text/event-stream',authorization:auth,...(sid?{'mcp-session-id':sid,'mcp-protocol-version':'2025-06-18'}:{})},body:JSON.stringify({jsonrpc:'2.0',id:++seq,method,params:p})});\n            sid = r.headers.get('mcp-session-id') ?? sid;\n            const raw = await r.text();\n            const data = raw.startsWith('data:') || raw.includes('\\ndata:') ? JSON.parse(raw.split('\\n').find(l=>l.startsWith('data:'))!.slice(5)) : JSON.parse(raw);\n            return data;\n          };\n          await rpc('initialize',{protocolVersion:'2025-06-18',capabilities:{},clientInfo:{name:'scenario-replay',version:'1'}});\n          const call = async (name:string,args:unknown) => {\n            const r = await rpc('tools/call',{name,arguments:args});\n            if (r.error) return {error:r.error};\n            const v = r.result;\n            if(v.isError) return {error:v.content};\n            if(v.structuredContent) return v.structuredContent;\n            const text = v.content?.filter((c:any)=>c.type==='text').map((c:any)=>c.text).join('\\n');\n            try{return JSON.parse(text);}catch{return {error:text};}\n          };\n          const rows: string[] = [];\n          const ids: string[] = [];\n          const links: string[] = [];\n          for (const tool of ['t3_thread_launch','delegate_task','create_threads']) {\n            const title = tool === 't3_thread_launch' ? 'Launched child' : tool === 'delegate_task' ? 'Delegated child' : 'Batch child';\n            const args = tool === 't3_thread_launch' ? {title,interactionMode:'plan'} : tool === 'delegate_task' ? {title,task:'Reply with Done.',mode:'wait',interactionMode:'plan'} : {threads:[{title,interactionMode:'plan'}]};\n            let result = await call(tool,args);\n            const rejected = !!result.error;\n            if (rejected) {\n              if (tool !== 'create_threads') args.interactionMode = 'inherit';\n              else args.threads[0].interactionMode = 'inherit';\n              result = await call(tool,args);\n            }\n            const child = result.threadId ?? result.childThreadId ?? result.threads?.[0]?.threadId;\n            if(!child) throw new Error('No child from '+tool+': '+JSON.stringify(result));\n            ids.push(child);\n            const read = await call('t3_thread_read',{threadId:child});\n            NodeFS.writeFileSync(session.cwd+'/.git/'+tool+'.json',JSON.stringify(read,null,2));\n            const thread = read.thread ?? read;\n            links.push(thread.link);\n            if (tool === 't3_thread_launch') {\n              const parent = await call('t3_thread_read',{threadId:process.env.T3CODE_THREAD_ID});\n              NodeFS.writeFileSync(session.cwd+'/.git/parent-link.json',JSON.stringify(parent.thread.link));\n            }\n            rows.push(`| ${tool} | ${rejected ? 'Rejected; retried inherit' : 'Accepted'} | ${thread.interactionMode} | ${thread.runtimeMode} |`);\n          }\n          const success = rows.every(r=>r.includes('| default |'));\n          const text = '# Child mode verification\\n\\nDefault parent \u00b7 Full access \u00b7 Legacy plan control disabled\\n\\nRequested interactionMode: plan on all three tools.\\n\\n| Tool | Explicit plan request | Child mode | Permissions |\\n| --- | --- | --- | --- |\\n'+rows.join('\\n')+'\\n\\n'+(success?'All children inherited default mode.':'BUG: children entered plan mode.')+'\\n\\n'+links.join(' \u00b7 ');\n          NodeFS.writeFileSync(session.cwd+'/.git/child-links.json',JSON.stringify(links));\n          send({method:'session/update',params:{sessionId,update:{sessionUpdate:'agent_message_chunk',content:{type:'text',text}}}});\n          return {stopReason:'end_turn'};\n        }\n";
  writeFileSync(replayPath,original.replace('        const turns = loadTurns(session.model);',injection+'\n        const turns = loadTurns(session.model);'));
  try {
    const project = await t3.project('Mode inheritance');
    await t3.thread({project,title:'Default parent',messages:['PROVE_CHILD_MODES']});
    const parentLink = JSON.parse(readFileSync(project+'/.git/parent-link.json','utf8'));
    const route = (link: string) => {const match = /t3-thread:\/\/v2\/([^/]+)\/([^)]+)/.exec(link)!; return '/'+match[1]+'/'+encodeURIComponent(match[2]);};
    await t3.open();
    await screen.getByRole('button', 'Settings', {exact:true}).waitFor({state:'visible'});
    await app.open(route(parentLink));
    await screen.getByText('Child mode verification',{exact:true}).waitFor({state:'visible'});
    await screen.getByRole('button','Toggle thread details panel').tap();
    await screen.getByText('Child mode verification',{exact:true}).scrollIntoView();
    const stableCapture = async (label: string) => {
      let previous = await app.screenshot(label+'-settling');
      for (let attempt=0; attempt<10; attempt++) {
        await new Promise(resolve=>setTimeout(resolve,500));
        const next = await app.screenshot(label);
        if(readFileSync(previous).equals(readFileSync(next))) return next;
        previous=next;
      }
      throw new Error('Capture never stabilized: '+label);
    };
    await stableCapture('child-mode-results');
    const links = JSON.parse(readFileSync(project+'/.git/child-links.json','utf8')) as string[];
    for (const [index, link] of links.entries()) {
      await app.open(route(link));
      await screen.getByRole('textbox').waitFor({state:'visible'});
      await stableCapture('child-'+(index+1));
    }
    await app.open(route(parentLink));
    await expect(screen.getByText('All children inherited default mode.',{exact:true})).toBeVisible();
  } finally {writeFileSync(replayPath,original);}
});
