import * as Effect from 'effect/Effect';
import * as Layer from 'effect/Layer';
import * as Schema from 'effect/Schema';
import { Socket } from 'effect/socket';
import { RpcClient, RpcSerialization } from 'effect/rpc';
import { WsRpcGroup, ORCHESTRATION_PROTOCOL_VERSION, ORCHESTRATION_PROTOCOL_HEADER, CommandId, ThreadId, ProjectId, ProviderInstanceId, MessageId } from '@t3tools/contracts';
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
const [action,origin,tokenFile,outFile,arg]=process.argv.slice(2);
const token=readFileSync(tokenFile,'utf8').trim();
const headers={Authorization:`Bearer ${token}`,'Content-Type':'application/json',[ORCHESTRATION_PROTOCOL_HEADER]:String(ORCHESTRATION_PROTOCOL_VERSION)};
const req=async(path:string,body?:unknown)=>{const r=await fetch(origin+path,{headers, ...(body?{method:'POST',body:JSON.stringify(body)}:{})});if(!r.ok)throw Error(`${path} ${r.status} ${await r.text()}`);return r.json()};
const ticket=await req('/api/auth/websocket-ticket',{});
const protocol=RpcClient.layerProtocolSocket().pipe(Layer.provide(Socket.layerWebSocket(`${origin.replace(/^http/,'ws')}/ws?orchestrationProtocol=${ORCHESTRATION_PROTOCOL_VERSION}&wsTicket=${encodeURIComponent(ticket.ticket)}`).pipe(Layer.provide(Socket.layerWebSocketConstructorGlobal))),Layer.provide(RpcSerialization.layerJson));
const a=ThreadId.make('capture-garden-a'),b=ThreadId.make('capture-garden-b'),p=ProjectId.make('capture-garden-project');
const run=Effect.gen(function*(){
const client=yield* RpcClient.make(WsRpcGroup);
if(action==='projection')return yield* client['orchestration.getThreadProjection']({threadId:a});
if(action==='config')return yield* client['server.getConfig']({});
if(action==='shell')return yield* Effect.promise(()=>req('/api/orchestration/shell'));
if(action==='seed'){
 mkdirSync('/tmp/lead-24651-r1b/capture/garden-workspace',{recursive:true});
 const shell:any=yield* Effect.promise(()=>req('/api/orchestration/shell'));
 if(!shell.projects.some((x:any)=>x.id===p))yield* Effect.promise(()=>req('/api/projects/mutate',{type:'project.create',commandId:crypto.randomUUID(),projectId:p,title:'Fictional Garden',workspaceRoot:'/tmp/lead-24651-r1b/capture/garden-workspace'}));
 for(let i=0;i<12;i++)if(!shell.threads.some((x:any)=>x.id===(i===0?a:i===1?b:`capture-stopped-${i}`)))yield* client['orchestration.dispatchCommand']({type:'thread.create',createdBy:'user',creationSource:'mobile',commandId:CommandId.make(crypto.randomUUID()),threadId:i===0?a:i===1?b:ThreadId.make(`capture-stopped-${i}`),projectId:p,title:i===0?'A · Garden streaming':i===1?'B · Idle notebook':`Garden notes ${String(i).padStart(2,'0')}`,modelSelection:{instanceId:ProviderInstanceId.make('codex'),model:'gpt-6.1-sol'},runtimeMode:'approval-required',interactionMode:'default',branch:null,worktreePath:null});
 return {seeded:12};
}
if(action==='stream')return yield* client['orchestration.dispatchCommand']({type:'message.dispatch',createdBy:'user',creationSource:'mobile',commandId:CommandId.make(crypto.randomUUID()),threadId:a,messageId:MessageId.make(crypto.randomUUID()),text:'Write 600 numbered short paragraphs about a fictional garden. Output the paragraphs directly. Do not use tools or edit files. Keep writing until all 600 are finished.',attachments:[],dispatchMode:{type:'start_immediately'}});
if(action==='rename')return yield* client['orchestration.dispatchCommand']({type:'thread.metadata.update',commandId:CommandId.make(crypto.randomUUID()),threadId:a,title:arg||'A · Garden renamed live'});
if(action==='stop')return yield* client['orchestration.dispatchCommand']({type:'thread.stop',commandId:CommandId.make(crypto.randomUUID()),threadId:a});
if(action==='legacy-stop'){
 const projection=yield* client['orchestration.getThreadProjection']({threadId:a});
 const active=projection.runs.find(r=>['preparing','starting','running','waiting','queued'].includes(r.status));
 return active?yield* client['orchestration.dispatchCommand']({type:'run.interrupt',commandId:CommandId.make(crypto.randomUUID()),threadId:a,runId:active.id}):{stopped:true};
}
throw Error('unknown action');
});
const result=await Effect.runPromise(Effect.scoped(run.pipe(Effect.provide(protocol))));
writeFileSync(outFile,JSON.stringify(result,null,2));console.log(`${action}: wrote ${outFile}`);
