import { readFileSync } from "node:fs";

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

import { isAtLeast, SECURITY_FLOORS } from "./dependencyFloors";

// 读取本包 package.json 声明版本（相对本测试文件 ../../ → apps/web/package.json）。
function declaredVersions(): Record<string, string> {
  const raw = readFileSync(
    new URL("../../package.json", import.meta.url),
    "utf-8",
  );
  const pkg = JSON.parse(raw) as {
    dependencies?: Record<string, string>;
    devDependencies?: Record<string, string>;
  };
  return { ...pkg.devDependencies, ...pkg.dependencies };
}

describe("SECURITY_FLOORS 锁定安全下界（CR-C1）", () => {
  const declared = declaredVersions();

  it.each(Object.keys(SECURITY_FLOORS))(
    "%s 声明版本不得低于安全下界",
    (name) => {
      const version = declared[name];
      if (version === undefined) {
        throw new Error(`${name} 未在 package.json 声明`);
      }
      const floor = SECURITY_FLOORS[name as keyof typeof SECURITY_FLOORS];
      expect(
        isAtLeast(version, floor),
        `${name}@${version} 低于安全下界 ${floor}`,
      ).toBe(true);
    },
  );
});

describe("isAtLeast 语义版本比较", () => {
  it("相等即满足", () => {
    expect(isAtLeast("15.5.20", "15.5.20")).toBe(true);
  });

  it("patch 更高满足、更低不满足", () => {
    expect(isAtLeast("19.2.7", "19.2.0")).toBe(true);
    expect(isAtLeast("19.2.0", "19.2.7")).toBe(false);
  });

  it("minor 边界", () => {
    expect(isAtLeast("15.5.0", "15.1.3")).toBe(true);
    expect(isAtLeast("15.1.3", "15.5.20")).toBe(false);
  });

  it("major 边界", () => {
    expect(isAtLeast("19.0.0", "18.9.9")).toBe(true);
    expect(isAtLeast("18.9.9", "19.0.0")).toBe(false);
  });

  it("去除前导 ^ / ~ 范围符", () => {
    expect(isAtLeast("^19.2.7", "19.2.7")).toBe(true);
    expect(isAtLeast("~19.2.7", "19.2.7")).toBe(true);
    expect(isAtLeast("19.2.0", "^19.2.7")).toBe(false);
  });

  it("缺省段按 0 计", () => {
    expect(isAtLeast("15", "15.0.0")).toBe(true);
    expect(isAtLeast("15.5", "15.5.0")).toBe(true);
    expect(isAtLeast("15", "15.5.0")).toBe(false);
  });
});
