import * as http from 'node:http';
import * as https from 'node:https';
import * as fs from 'node:fs';
import * as child from 'node:child_process';
import * as NodeServices from '@effect/platform-node/NodeServices';
import {EnvironmentId, ThreadId, ProviderInstanceId} from '@t3tools/contracts';
import * as Effect from 'effect/Effect';
import * as Layer from 'effect/Layer';
import * as Option from 'effect/Option';
import * as Config from './source/apps/server/src/config.ts';
import * as Environment from './source/apps/server/src/environment/ServerEnvironment.ts';
import * as Broker from './source/apps/server/src/mcp/PreviewAutomationBroker.ts';
import * as Manager from './source/apps/server/src/preview/Manager.ts';
import * as Desktop from './source/apps/server/src/preview/DesktopBrowserChannel.ts';
import * as Browser from './source/apps/server/src/preview/ServerBrowser.ts';
import * as Executable from './source/apps/server/src/preview/PreviewBrowser.ts';
const reply = (_req, res) => {res.writeHead(200, {'content-type':'text/html'}); res.end('<!doctype html><title>18555 recovery</title><h1>Working page</h1>');};
const good = http.createServer(reply);
const bad = https.createServer({key:fs.readFileSync('<LOCAL_FIXTURE_KEY_PATH>'),cert:fs.readFileSync('<LOCAL_FIXTURE_CERT_PATH>')},reply);
await Promise.all([new Promise<void>(r=>good.listen(18080,'127.0.0.1',r)),new Promise<void>(r=>bad.listen(18443,'127.0.0.1',r))]);
const scope = {environmentId:EnvironmentId.make('proof-18555'),thread:{threadId:ThreadId.make('proof-18555'),providerSessionId:'proof-18555',providerInstanceId:ProviderInstanceId.make('codex')},client:undefined,requestNamespace:'proof-18555',capabilities:new Set(['preview'] as const),issuedAt:Date.now()};
const executable = '/home/ubuntu/.cache/ms-playwright/chromium_headless_shell-1223/chrome-headless-shell-linux64/chrome-headless-shell';
const deps = Layer.mergeAll(Broker.layer,Manager.layer,Desktop.layer,Layer.succeed(Environment.ServerEnvironment,{getEnvironmentId:Effect.succeed(scope.environmentId),getDescriptor:Effect.die('unused')}),Layer.succeed(Executable.PreviewBrowser,{executable:Effect.succeed(executable),installed:Effect.succeed(Option.some(executable))})).pipe(Layer.provideMerge(Config.layerTest(process.cwd(),{prefix:'18555-proof-'})),Layer.provideMerge(NodeServices.layer));
console.log(JSON.stringify({sha:child.execFileSync('git',['-C',fs.realpathSync(new URL('./source',import.meta.url)),'rev-parse','HEAD'],{encoding:'utf8'}).trim(),browser:executable,viewport:[1280,800],fixture:'local self-signed HTTPS :18443; unsafe port :1; HTTP recovery :18080'}));
try {
await Effect.runPromise(Effect.scoped(Effect.gen(function*(){
 yield* Browser.ServerBrowser;
 const broker = yield* Broker.PreviewAutomationBroker;
 yield* Effect.yieldNow;
 const open = yield* broker.invoke({scope,operation:'open',input:{open:false,reuseExistingTab:false}});
 const tabId = open.tabId;
 const call = (operation, input={})=>broker.invoke({scope,tabId,operation,input});
 for(const [name,url] of [['reporter','https://self-signed.badssl.com/'],['certificate','https://127.0.0.1:18443/'],['unsafe-port','http://127.0.0.1:1/'],['recovery','http://127.0.0.1:18080/']]) {
  const navigation = yield* call('navigate',{url}).pipe(Effect.result);
  console.log(JSON.stringify({name,navigation}));
  const committed = yield* call('waitFor',name==='recovery'?{text:'Working page'}:{urlIncludes:'chrome-error://'});
  console.log(JSON.stringify({name,operation:'waitFor',result:committed}));
  for(const operation of ['status','snapshot']) {
   const result = yield* call(operation).pipe(Effect.result);
   if(result._tag==='Success') {const v=result.success; if(v.screenshot) v.screenshot={mimeType:v.screenshot.mimeType,width:v.screenshot.width,height:v.screenshot.height}; console.log(JSON.stringify({name,operation,result:v}));}
   else console.log(JSON.stringify({name,operation,result}));
  }
 }
 yield* call('close');
})).pipe(Effect.provide(Browser.layer.pipe(Layer.provideMerge(deps)))));
} finally {good.closeAllConnections();bad.closeAllConnections();await Promise.all([new Promise(r=>good.close(r)),new Promise(r=>bad.close(r))]);}
