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

import {
  createLogger,
  isLevelEnabled,
  normalizeLogLevel,
  writeLog,
} from "./logger.js";

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

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

describe("logger", () => {
  it("normalizes LOG_LEVEL and falls back to info", () => {
    expect(normalizeLogLevel("debug")).toBe("debug");
    expect(normalizeLogLevel(" WARN ")).toBe("warn");
    expect(normalizeLogLevel("nope")).toBe("info");
    expect(normalizeLogLevel("")).toBe("info");
  });

  it("enables messages at or above the configured threshold", () => {
    expect(isLevelEnabled("debug", "info")).toBe(false);
    expect(isLevelEnabled("info", "info")).toBe(true);
    expect(isLevelEnabled("error", "warn")).toBe(true);
    expect(isLevelEnabled("info", "warn")).toBe(false);
    expect(isLevelEnabled("debug", "debug")).toBe(true);
  });

  it("writes only enabled levels", () => {
    process.env.LOG_LEVEL = "warn";
    const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => undefined);
    const logSpy = vi.spyOn(console, "log").mockImplementation(() => undefined);

    writeLog("info", "hidden");
    writeLog("warn", "visible");

    expect(logSpy).not.toHaveBeenCalled();
    expect(warnSpy).toHaveBeenCalledWith("visible");
  });

  it("prefixes scoped logger messages", () => {
    process.env.LOG_LEVEL = "debug";
    const debugSpy = vi.spyOn(console, "debug").mockImplementation(() => undefined);

    createLogger("llm").debug("message");

    expect(debugSpy).toHaveBeenCalledWith("[llm]", "message");
  });
});
