// SPEC: PJ2026-01060505 Workbench Performance draft-2026-06-17-p0.
// Responsibility: Code Agent trace timing and durable projection tests.

import assert from "node:assert/strict";
import { test } from "bun:test";

import { createCodeAgentTraceStore, createDurableCodeAgentTraceStore } from "./code-agent-trace-store.ts";

test("code agent trace store keeps assistant deltas outside event count", () => {
  const traceStore = createCodeAgentTraceStore({ maxEvents: 6000 });
  const traceId = "trc_trace-store-assistant-stream";
  traceStore.append(traceId, { type: "request", status: "accepted", label: "request:accepted" });
  for (let index = 0; index < 6200; index += 1) {
    traceStore.appendAssistantDelta(traceId, {
      itemId: "item_assistant_stream",
      chunk: `chunk-${index} `,
      waitingFor: "turn/completed"
    });
  }
  const snapshot = traceStore.snapshot(traceId);
  assert.equal(snapshot.eventCount, 1);
  assert.equal(snapshot.events.length, 1);
  assert.equal(snapshot.events[0].label, "request:accepted");
  assert.equal(snapshot.assistantStreams.length, 1);
  assert.equal(snapshot.assistantStreams[0].chunkCount, 6200);
  assert.equal(snapshot.waitingFor, "turn/completed");
});

test("code agent trace store dedupes repeated AgentRun source events", () => {
  const traceStore = createCodeAgentTraceStore({ maxEvents: 20 });
  const traceId = "trc_trace-store-agentrun-dedupe";
  const event = {
    type: "backend",
    status: "running",
    label: "agentrun:backend:resource-bundle-materialized",
    source: "agentrun",
    sourceSeq: 42,
    createdAt: "2026-06-01T00:00:00.000Z"
  };
  traceStore.append(traceId, event);
  traceStore.append(traceId, event);
  traceStore.append(traceId, { ...event, type: "assistant", label: "agentrun:assistant:message", message: "OK" });
  const snapshot = traceStore.snapshot(traceId);
  assert.equal(snapshot.eventCount, 2);
  assert.deepEqual(snapshot.events.map((item) => item.label), ["agentrun:backend:resource-bundle-materialized", "agentrun:assistant:message"]);
});

test("durable code agent trace store projects appended events without counting assistant deltas", () => {
  const writes = [];
  const workbenchWrites = [];
  const baseStore = createCodeAgentTraceStore({ maxEvents: 20 });
  const traceStore = createDurableCodeAgentTraceStore({
    traceStore: baseStore,
    traceEventStore: {
      writeAgentTraceEvent(params, requestMeta) {
        writes.push({ params, requestMeta });
        return { written: true };
      }
    },
    workbenchEventWriter(event, requestMeta) {
      workbenchWrites.push({ event, requestMeta });
      return { written: true };
    }
  });
  const traceId = "trc_trace-store-durable-projection";

  traceStore.append(traceId, { type: "request", status: "accepted", label: "request:accepted", sessionId: "ses_trace_store_durable" });
  traceStore.appendAssistantDelta(traceId, { itemId: "assistant", chunk: "hello" });

  const snapshot = traceStore.snapshot(traceId);
  assert.equal(snapshot.eventCount, 1);
  assert.equal(snapshot.assistantStreams.length, 1);
  assert.equal(writes.length, 1);
  assert.equal(writes[0].params.event.traceId, traceId);
  assert.equal(writes[0].params.event.seq, 1);
  assert.equal(writes[0].requestMeta.agentSessionId, "ses_trace_store_durable");
  assert.equal(workbenchWrites.length, 1);
  assert.equal(workbenchWrites[0].event.traceId, traceId);
  assert.equal(workbenchWrites[0].requestMeta.sessionId, undefined);
});

test("code agent trace store retains six thousand regular events", () => {
  const traceStore = createCodeAgentTraceStore({ maxEvents: 6000 });
  const traceId = "trc_trace-store-regular-events";
  for (let index = 0; index < 6001; index += 1) {
    traceStore.append(traceId, { type: "trace", status: "observed", label: `event:${index}` });
  }
  const snapshot = traceStore.snapshot(traceId);
  assert.equal(snapshot.eventCount, 6000);
  assert.equal(snapshot.events.length, 6000);
  assert.equal(snapshot.events[0].label, "event:1");
  assert.equal(snapshot.events.at(-1).label, "event:6000");
});

test("code agent trace store preserves upstream event timestamps", () => {
  const traceStore = createCodeAgentTraceStore({ maxEvents: 10 });
  const traceId = "trc_trace-store-upstream-time";
  traceStore.append(traceId, {
    type: "backend",
    status: "running",
    label: "agentrun:backend:turn/completed",
    backend: "agentrun-v01/codex",
    createdAt: "2026-06-01T16:35:40.939Z"
  }, { now: "2026-06-01T16:35:56.171Z" });
  const snapshot = traceStore.snapshot(traceId);
  assert.equal(snapshot.events[0].createdAt, "2026-06-01T16:35:40.939Z");
  assert.equal(snapshot.events[0].appendedAt, "2026-06-01T16:35:56.171Z");
  assert.equal(snapshot.events[0].eventType, "backend");
  assert.equal(snapshot.events[0].backend, "agentrun-v01/codex");
  assert.equal(snapshot.elapsedMs, 0);
});

test("code agent trace store anchors trace time to replayed upstream events", () => {
  const traceStore = createCodeAgentTraceStore({ maxEvents: 20 });
  const traceId = "trc_trace-store-replayed-upstream-time";
  traceStore.ensure(traceId, { now: "2026-06-17T13:03:50.000Z" });
  traceStore.append(traceId, {
    type: "backend",
    status: "running",
    label: "agentrun:backend:run-created",
    createdAt: "2026-06-17T12:56:13.650Z"
  }, { now: "2026-06-17T13:03:51.000Z" });
  traceStore.append(traceId, {
    type: "assistant",
    status: "completed",
    label: "agentrun:assistant:message",
    message: "OK",
    terminal: true,
    createdAt: "2026-06-17T12:56:39.484Z"
  }, { now: "2026-06-17T13:03:52.000Z" });

  const snapshot = traceStore.snapshot(traceId);
  assert.equal(snapshot.createdAt, "2026-06-17T12:56:13.650Z");
  assert.equal(snapshot.startedAt, "2026-06-17T12:56:13.650Z");
  assert.equal(snapshot.updatedAt, "2026-06-17T12:56:39.484Z");
  assert.equal(snapshot.finishedAt, "2026-06-17T12:56:39.484Z");
  assert.equal(snapshot.elapsedMs, 25834);
});

test("code agent trace store freezes terminal traces against stale post-terminal events", () => {
  const traceStore = createCodeAgentTraceStore({ maxEvents: 20 });
  const traceId = "trc_trace-store-terminal-freeze";
  traceStore.append(traceId, {
    type: "backend",
    status: "running",
    label: "agentrun:backend:turn/started",
    createdAt: "2026-06-17T12:56:27.325Z"
  });
  traceStore.append(traceId, {
    type: "result",
    status: "completed",
    label: "agentrun:result:completed",
    message: "AgentRun result is ready for HWLAB short-connection polling.",
    terminal: true,
    createdAt: "2026-06-17T12:56:41.293Z"
  });
  traceStore.append(traceId, {
    type: "result",
    status: "completed",
    label: "agentrun:result:completed",
    message: "AgentRun result is ready for HWLAB short-connection polling.",
    terminal: true,
    createdAt: "2026-06-17T12:56:41.293Z"
  });
  traceStore.append(traceId, {
    type: "backend",
    status: "running",
    label: "agentrun:backend:runner-claim-waiting-for-stale-lease",
    createdAt: "2026-06-17T13:04:49.500Z"
  });

  const snapshot = traceStore.snapshot(traceId);
  assert.equal(snapshot.eventCount, 2);
  assert.deepEqual(snapshot.events.map((item) => item.label), ["agentrun:backend:turn/started", "agentrun:result:completed"]);
  assert.equal(snapshot.status, "completed");
  assert.equal(snapshot.updatedAt, "2026-06-17T12:56:41.293Z");
  assert.equal(snapshot.finishedAt, "2026-06-17T12:56:41.293Z");
  assert.equal(snapshot.elapsedMs, 13968);
});
