// Scratch driver for issue 36036; not committed.
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import { Socket } from "effect/socket";
import { RpcClient, RpcSerialization } from "effect/rpc";
import { ORCHESTRATION_PROTOCOL_VERSION, WsRpcGroup } from "@t3tools/contracts";

const [origin, credential] = process.argv.slice(2);
const session = await fetch(`${origin}/api/auth/browser-session`, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ credential }),
});
if (!session.ok) throw new Error(`pair failed ${session.status}`);
const cookie = session.headers.get("set-cookie")!.split(";")[0]!;
const ticketRes = await fetch(`${origin}/api/auth/websocket-ticket`, {
  method: "POST",
  headers: { cookie },
});
if (!ticketRes.ok) throw new Error(`ticket failed ${ticketRes.status} ${await ticketRes.text()}`);
const { ticket } = (await ticketRes.json()) as { ticket: string };

// Probe: a trivial authenticated HTTP request; its latency is bounded below by main-thread stalls.
const probes: number[] = [];
let probing = true;
const probe = (async () => {
  while (probing) {
    const t0 = performance.now();
    await fetch(`${origin}/api/auth/session`, { headers: { cookie } }).then((r) => r.arrayBuffer());
    probes.push(performance.now() - t0);
    await new Promise((r) => setTimeout(r, 50));
  }
})();

const layer = RpcClient.layerProtocolSocket().pipe(
  Layer.provide(
    Socket.layerWebSocket(
      `${origin.replace("http:", "ws:")}/ws?orchestrationProtocol=${ORCHESTRATION_PROTOCOL_VERSION}&wsTicket=${encodeURIComponent(ticket)}`,
    ).pipe(Layer.provide(Socket.layerWebSocketConstructorGlobal)),
  ),
  Layer.provide(RpcSerialization.layerJson),
);
const day = (d: Date) => d.toISOString().slice(0, 10);
const now = new Date();
const since = new Date(now.getTime() - 29 * 86400_000);
const call = (awaitRefresh: boolean) =>
  Effect.gen(function* () {
    const client = yield* RpcClient.make(WsRpcGroup);
    return yield* client["server.getUsageSummary"]({
      sinceDay: day(since),
      untilDay: day(now),
      timeZone: "UTC",
      awaitRefresh,
    } as never);
  }).pipe(Effect.scoped, Effect.provide(layer));

const t0 = performance.now();
const summary = (await Effect.runPromise(call(true))) as Record<string, unknown>;
const elapsed = performance.now() - t0;
probing = false;
await probe;
const sorted = [...probes].sort((a, b) => a - b);
const json = JSON.stringify(summary);
console.log(
  JSON.stringify({
    coldSummaryMs: Math.round(elapsed),
    probes: probes.length,
    probeP50Ms: Math.round(sorted[Math.floor(sorted.length / 2)]!),
    probeMaxMs: Math.round(sorted.at(-1)!),
    probesOver250Ms: probes.filter((p) => p > 250).length,
    summaryBytes: json.length,
    summaryKeys: Object.keys(summary),
    sources: summary.sources, scanDurationMs: summary.scanDurationMs, buckets: (summary.buckets as unknown[]).length,
  }),
);
process.exit(0);
