import fs from "fs";
import os from "os";
import path from "path";
import { afterEach, describe, expect, it } from "vitest";
import { findFailureLocation, formatLocation, renderCodeFrame } from "./code-frames.mjs";

const cleanups = [];

afterEach(() => {
  while (cleanups.length > 0) {
    cleanups.pop()();
  }
});

describe("code frame presentation", () => {
  it("finds a location from structured failure metadata", () => {
    expect(
      findFailureLocation({
        location: {
          path: "/tmp/example.ts",
          line: 10,
          column: 2,
        },
      })
    ).toEqual({
      path: "/tmp/example.ts",
      line: 10,
      column: 2,
    });
  });

  it("renders a code frame for a local file", () => {
    const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "testkit-code-frame-"));
    cleanups.push(() => fs.rmSync(tempDir, { recursive: true, force: true }));
    const filePath = path.join(tempDir, "example.ts");
    fs.writeFileSync(
      filePath,
      [
        "export function run() {",
        "  const value = 1;",
        "  return value + missing;",
        "}",
      ].join("\n")
    );

    const lines = renderCodeFrame(
      {
        path: filePath,
        line: 3,
        column: 18,
      },
      { cwd: tempDir }
    );

    expect(lines.join("\n")).toContain("example.ts:3:18");
    expect(lines.join("\n")).toContain("return value + missing;");
  });

  it("formats locations relative to the cwd", () => {
    expect(
      formatLocation(
        {
          path: "/tmp/example.ts",
          line: 7,
          column: 3,
        },
        "/tmp"
      )
    ).toBe("example.ts:7:3");
  });
});
