import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { ensureItemLog, getItemLogPath, initItemLogs, logItemEvent, shutdownItemLogs } from "../src/main/item-log";

const tempDirs: string[] = [];

afterEach(() => {
  shutdownItemLogs();
  for (const dir of tempDirs.splice(0)) {
    fs.rmSync(dir, { recursive: true, force: true });
  }
});

describe("item-log", () => {
  it("creates a persistent item log file", () => {
    const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-ilog-"));
    tempDirs.push(baseDir);

    initItemLogs(baseDir);
    const logPath = ensureItemLog({
      itemId: "item-1",
      packageId: "pkg-1",
      packageName: "Test Paket",
      fileName: "episode.part2.rar",
      targetPath: "C:\\downloads\\Test Paket\\episode.part2.rar"
    });

    expect(logPath).not.toBeNull();
    expect(fs.existsSync(logPath!)).toBe(true);

    const content = fs.readFileSync(logPath!, "utf8");
    expect(content).toContain("Item-Log Start");
    expect(content).toContain("episode.part2.rar");
  });

  it("writes detail events into the item log", async () => {
    const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-ilog-"));
    tempDirs.push(baseDir);

    initItemLogs(baseDir);
    ensureItemLog({
      itemId: "item-2",
      packageId: "pkg-2",
      packageName: "Detail Paket",
      fileName: "episode.part2.rar",
      targetPath: "C:\\downloads\\Detail Paket\\episode.part2.rar"
    });

    logItemEvent("item-2", "ERROR", "Entpack-Fehler", {
      archive: "episode.part2.rar",
      code: "missing_parts",
      detail: "Unexpected end of archive"
    });

    await new Promise((resolve) => setTimeout(resolve, 350));

    const logPath = getItemLogPath("item-2");
    expect(logPath).not.toBeNull();
    const content = fs.readFileSync(logPath!, "utf8");
    expect(content).toContain("Entpack-Fehler");
    expect(content).toContain("archive=episode.part2.rar");
    expect(content).toContain("code=missing_parts");
  });

  it("keeps traversal-like item ids inside the item log directory", () => {
    const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-ilog-"));
    tempDirs.push(baseDir);

    initItemLogs(baseDir);
    const logPath = ensureItemLog({
      itemId: "..\\..\\outside",
      packageId: "pkg-traversal",
      packageName: "Traversal Paket",
      fileName: "episode.part2.rar",
      targetPath: "C:\\downloads\\Traversal Paket\\episode.part2.rar"
    });

    expect(logPath).not.toBeNull();
    const logsDir = path.resolve(path.join(baseDir, "item-logs"));
    const resolvedLogPath = path.resolve(logPath!);
    expect(resolvedLogPath === logsDir || resolvedLogPath.startsWith(`${logsDir}${path.sep}`)).toBe(true);
  });
});
