import { describe, it, expect, beforeAll, afterAll } from "vitest";
import { mkdtempSync, rmSync, mkdirSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { execSync } from "node:child_process";
import { scanProjectsInDir } from "@/lib/scanner/auto-scan";

let root: string;

beforeAll(() => {
  root = mkdtempSync(join(tmpdir(), "pm-scan-"));
  for (const name of ["alpha", "beta"]) {
    const dir = join(root, name);
    mkdirSync(dir);
    execSync("git init -b main", { cwd: dir });
    execSync("git config user.email t@t.io", { cwd: dir });
    execSync("git config user.name tester", { cwd: dir });
    writeFileSync(join(dir, "package.json"), JSON.stringify({ name, version: "0.1.0" }));
    execSync("git add . && git commit -m 'init'", { cwd: dir });
  }
  // a non-git directory should be skipped
  mkdirSync(join(root, "not-a-repo"));
  writeFileSync(join(root, "not-a-repo", "readme.md"), "hi");
});

afterAll(() => {
  rmSync(root, { recursive: true, force: true });
});

describe("scanProjectsInDir", () => {
  it("finds only git repos under the root", async () => {
    const results = await scanProjectsInDir(root);
    const names = results.map((r) => r.name).sort();
    expect(names).toEqual(["alpha", "beta"]);
  });

  it("returns name + path + git state for each project", async () => {
    const results = await scanProjectsInDir(root);
    const alpha = results.find((r) => r.name === "alpha");
    expect(alpha).toBeDefined();
    expect(alpha!.path).toBe(join(root, "alpha"));
    expect(alpha!.branch).toBe("main");
    expect(alpha!.version).toBe("0.1.0");
    expect(alpha!.lastCommitHash).toMatch(/^[0-9a-f]{40}$/);
  });

  it("returns empty array if root does not exist", async () => {
    const results = await scanProjectsInDir("/nonexistent/path/xyz");
    expect(results).toEqual([]);
  });
});
