import { afterEach, beforeEach, describe, expect, test } from "bun:test";
import { mkdir, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, win32 } from "node:path";

import { scanDir, toImportSpecifier } from "../../scripts/build-common";

describe("scanDir", () => {
  let tempDir: string;

  beforeEach(async () => {
    tempDir = join(tmpdir(), `build-common-test-${Date.now()}`);
    await mkdir(tempDir, { recursive: true });
  });

  afterEach(async () => {
    await rm(tempDir, { force: true, recursive: true });
  });

  test("扫描空目录", async () => {
    const files = await scanDir(tempDir, "/");
    expect(files).toEqual([]);
  });

  test("扫描单文件", async () => {
    await writeFile(join(tempDir, "index.html"), "<html></html>");
    const files = await scanDir(tempDir, "/");
    expect(files).toEqual(["/index.html"]);
  });

  test("扫描嵌套目录", async () => {
    await mkdir(join(tempDir, "assets"), { recursive: true });
    await writeFile(join(tempDir, "index.html"), "");
    await writeFile(join(tempDir, "assets", "style.css"), "");
    await writeFile(join(tempDir, "assets", "app.js"), "");

    const files = await scanDir(tempDir, "/");
    expect(files.sort()).toEqual(["/assets/app.js", "/assets/style.css", "/index.html"]);
  });

  test("扫描多层嵌套", async () => {
    await mkdir(join(tempDir, "a", "b"), { recursive: true });
    await writeFile(join(tempDir, "a", "b", "deep.txt"), "");

    const files = await scanDir(tempDir, "/");
    expect(files).toEqual(["/a/b/deep.txt"]);
  });

  test("自定义前缀", async () => {
    await writeFile(join(tempDir, "file.txt"), "");
    const files = await scanDir(tempDir, "/static/");
    expect(files).toEqual(["/static/file.txt"]);
  });
});

describe("toImportSpecifier", () => {
  test("同目录文件生成正确的相对路径", () => {
    const result = toImportSpecifier("/project/.build", "/project/.build/file.txt");
    expect(result).toBe("file.txt");
  });

  test("子目录文件生成正确的相对路径", () => {
    const result = toImportSpecifier("/project/.build", "/project/.build/sub/file.txt");
    expect(result).toBe("sub/file.txt");
  });

  test("Windows 路径分隔符转换为正斜杠", () => {
    const result = toImportSpecifier("C:\\project\\.build", "C:\\project\\dist\\web\\assets\\app.js", win32.relative);
    expect(result).toBe("../dist/web/assets/app.js");
    expect(result).not.toContain("\\");
  });
});
