import { mkdtempSync, readFileSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { appendOutput, configureTaskOutput, taskFullOutput } from "../src/components/microservices/code-queue/src/task-output";
import { sanitizeTaskOutputText } from "../src/components/microservices/code-queue/src/output-redaction";
import type { JsonValue, QueueTask } from "../src/components/microservices/code-queue/src/types";

type JsonRecord = Record<string, unknown>;

function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
  if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
}

function fixtureTask(): QueueTask {
  const at = "2026-05-23T00:00:00.000Z";
  return {
    id: "codex_gh_auth_redaction_contract",
    queueId: "default",
    queueEnteredAt: at,
    prompt: "redaction fixture",
    basePrompt: "redaction fixture",
    referenceTaskIds: [],
    referenceInjection: null,
    providerId: "D601",
    cwd: "/workspace",
    model: "gpt-5.5",
    reasoningEffort: null,
    executionMode: "default",
    maxAttempts: 1,
    status: "running",
    createdAt: at,
    updatedAt: at,
    startedAt: at,
    finishedAt: null,
    readAt: null,
    currentAttempt: 1,
    currentMode: "initial",
    codexThreadId: null,
    activeTurnId: null,
    finalResponse: "",
    lastError: null,
    lastJudge: null,
    judgeFailCount: 0,
    promptHistory: [],
    output: [],
    events: [],
    attempts: [],
    cancelRequested: false,
    nextPrompt: null,
    nextMode: null,
  };
}

function assertNoTokenFragments(value: string, label: string): void {
  assertCondition(!/\bgh[pousr]_[A-Za-z0-9_]{6,}\b/u.test(value), `${label} must redact gh token-like values`, value);
  assertCondition(!/\bgithub_pat_[A-Za-z0-9_]{6,}\b/u.test(value), `${label} must redact GitHub PAT-like values`, value);
  assertCondition(!/Token:\s*\S+/iu.test(value), `${label} must not expose raw gh auth token lines`, value);
  assertCondition(!/Token scopes?:\s*\S+/iu.test(value), `${label} must not expose raw gh auth scope lines`, value);
}

export function runCodeQueueGhAuthRedactionContract(): JsonRecord {
  const tmp = mkdtempSync(join(tmpdir(), "code-queue-gh-auth-redaction-"));
  const task = fixtureTask();
  let seq = 0;
  try {
    configureTaskOutput({
      config: { maxInMemoryOutputRecords: 1000, outputArchiveDir: tmp },
      allocateSeq: () => {
        seq += 1;
        return seq;
      },
      errorToJson: (error: unknown): JsonValue => error instanceof Error ? { message: error.message } : String(error),
      logger: () => undefined,
      markTaskDirty: () => undefined,
      nowIso: () => "2026-05-23T00:00:01.000Z",
      schedulePersistState: () => undefined,
    });

    const rawGhAuth = [
      "github.com",
      "  \u2713 Logged in to github.com account example (keyring)",
      "  - Active account: true",
      "  - Git operations protocol: ssh",
      "  - Token: ghp_abcdef1234567890abcdef1234567890",
      "  - Token scopes: 'repo', 'read:org'",
      "generic token=github_pat_abcdef1234567890abcdef1234567890",
    ].join("\n");
    const sanitized = sanitizeTaskOutputText(rawGhAuth);
    assertNoTokenFragments(sanitized, "direct sanitizer output");
    assertCondition(sanitized.includes("[redacted gh auth status line]"), "sanitizer must redact gh auth status lines", sanitized);
    assertCondition(sanitized.includes("bun scripts/cli.ts gh auth status"), "sanitizer must include UniDesk gh wrapper hint", sanitized);

    appendOutput(task, "command", `${rawGhAuth}\n`, "item/commandExecution/outputDelta", "call-gh-auth", true);
    const retained = JSON.stringify(task.output);
    const archived = readFileSync(join(tmp, `${task.id}.jsonl`), "utf8");
    const full = JSON.stringify(taskFullOutput(task));
    assertNoTokenFragments(retained, "retained output");
    assertNoTokenFragments(archived, "archived output");
    assertNoTokenFragments(full, "full output replay");
    assertCondition(full.includes("bun scripts/cli.ts gh auth status"), "full output replay must keep wrapper hint", full);

    return {
      ok: true,
      checks: [
        "raw gh auth status token and scope lines are redacted",
        "token-like GitHub values are redacted before retained output persistence",
        "output archive replay remains redacted",
        "redacted output nudges runner toward bun scripts/cli.ts gh auth status",
      ],
    };
  } finally {
    rmSync(tmp, { recursive: true, force: true });
  }
}

try {
  process.stdout.write(`${JSON.stringify(runCodeQueueGhAuthRedactionContract(), null, 2)}\n`);
} catch (error) {
  process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
  process.exit(1);
}
