import { afterEach, describe, expect, it, vi } from "vitest";

import {
  runWithLlmDebugLog,
  summarizeRequest,
  summarizeUrl,
} from "./llm-debug-log.js";

const originalEnv = { ...process.env };

afterEach(() => {
  process.env = { ...originalEnv };
  vi.restoreAllMocks();
});

describe("llm-debug-log", () => {
  it("summarizes text and media without leaking base64 payloads", () => {
    const request = {
      model: "vision-model",
      messages: [
        { role: "system", content: "Return JSON only." },
        {
          role: "user",
          content: [
            { type: "text", text: "x".repeat(180) },
            {
              type: "image_url",
              image_url: {
                url: "data:image/png;base64,aW1hZ2UgYnl0ZXM=",
              },
            },
            {
              type: "file",
              file: {
                filename: "quote.pdf",
                file_data: "data:application/pdf;base64,cGRmIGJ5dGVz",
              },
            },
          ],
        },
      ],
    };

    const summary = summarizeRequest(request);
    const serialized = JSON.stringify(summary);

    expect(summary.messages).toHaveLength(2);
    expect(summary.messages[1]).toMatchObject({
      contentType: "parts",
      partCount: 3,
      textLength: 180,
    });
    expect(summary.messages[1].textPreview).toHaveLength(123);
    expect(serialized).toContain('"kind":"data_url"');
    expect(serialized).toContain('"mimeType":"image/png"');
    expect(serialized).not.toContain("aW1hZ2UgYnl0ZXM=");
    expect(serialized).not.toContain("cGRmIGJ5dGVz");
  });

  it("does not include api keys in debug events", async () => {
    process.env.LOG_LEVEL = "debug";
    const debugSpy = vi.spyOn(console, "debug").mockImplementation(() => undefined);
    const request = {
      model: "chat-model",
      apiKey: "sk-secret",
      messages: [{ role: "user", content: "hello" }],
    };

    await runWithLlmDebugLog(
      { scope: "test", stage: "unit", label: "call", provider: "openai", model: "chat-model" },
      request,
      async () => ({
        choices: [{ finish_reason: "stop", message: { content: "world" } }],
        usage: { prompt_tokens: 1, completion_tokens: 1 },
      }),
    );

    const output = debugSpy.mock.calls.map((call) => String(call[0])).join("\n");
    expect(output).toContain('"event":"llm.request"');
    expect(output).toContain('"event":"llm.response"');
    expect(output).toContain('"textPreview":"hello"');
    expect(output).toContain('"textPreview":"world"');
    expect(output).not.toContain("sk-secret");
  });

  it("summarizes ordinary urls without query strings", () => {
    expect(summarizeUrl("https://example.test/path/to/image.jpg?token=secret")).toEqual({
      kind: "url",
      origin: "https://example.test",
      pathnamePreview: "/path/to/image.jpg",
    });
  });
});
