import { afterEach, beforeEach, describe, expect, test } from "bun:test";
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

import { bumpVersion, formatVersion, parseVersion, validateVersion } from "../../scripts/bump-version-logic";

describe("版本解析与校验", () => {
  test("parseVersion 解析有效版本", () => {
    expect(parseVersion("0.1.0")).toEqual([0, 1, 0]);
    expect(parseVersion("1.2.3")).toEqual([1, 2, 3]);
    expect(parseVersion("10.20.30")).toEqual([10, 20, 30]);
  });

  test("parseVersion 拒绝无效版本", () => {
    expect(() => parseVersion("invalid")).toThrow();
    expect(() => parseVersion("1.2")).toThrow();
    expect(() => parseVersion("1.2.3.4")).toThrow();
    expect(() => parseVersion("1.2.a")).toThrow();
  });

  test("validateVersion 接受有效版本", () => {
    expect(() => validateVersion("0.1.0")).not.toThrow();
    expect(() => validateVersion("1.2.3")).not.toThrow();
    expect(() => validateVersion("10.20.30")).not.toThrow();
  });

  test("validateVersion 拒绝无效版本", () => {
    expect(() => validateVersion("")).toThrow();
    expect(() => validateVersion("invalid")).toThrow();
    expect(() => validateVersion("1.2")).toThrow();
    expect(() => validateVersion("1.2.3.4")).toThrow();
    expect(() => validateVersion("1.0.0-beta.1")).toThrow();
    expect(() => validateVersion("v1.0.0")).toThrow();
  });

  test("formatVersion 格式化版本", () => {
    expect(formatVersion(0, 1, 0)).toBe("0.1.0");
    expect(formatVersion(1, 2, 3)).toBe("1.2.3");
    expect(formatVersion(10, 20, 30)).toBe("10.20.30");
  });
});

describe("版本升迁逻辑", () => {
  test("bumpVersion patch 升迁", () => {
    expect(bumpVersion("1.2.3", "patch")).toBe("1.2.4");
    expect(bumpVersion("0.1.0", "patch")).toBe("0.1.1");
    expect(bumpVersion("0.0.1", "patch")).toBe("0.0.2");
  });

  test("bumpVersion minor 危迁", () => {
    expect(bumpVersion("1.2.3", "minor")).toBe("1.3.0");
    expect(bumpVersion("0.1.0", "minor")).toBe("0.2.0");
    expect(bumpVersion("0.0.1", "minor")).toBe("0.1.0");
  });

  test("bumpVersion major 危迁", () => {
    expect(bumpVersion("1.2.3", "major")).toBe("2.0.0");
    expect(bumpVersion("0.1.0", "major")).toBe("1.0.0");
    expect(bumpVersion("0.0.1", "major")).toBe("1.0.0");
  });

  test("bumpVersion set 设置版本", () => {
    expect(bumpVersion("1.2.3", "set", "2.0.0")).toBe("2.0.0");
    expect(bumpVersion("0.1.0", "set", "0.2.0")).toBe("0.2.0");
  });

  test("bumpVersion set 拒绝无效版本", () => {
    expect(() => bumpVersion("1.2.3", "set", "invalid")).toThrow();
    expect(() => bumpVersion("1.2.3", "set", "1.0.0-beta.1")).toThrow();
  });
});

describe("写入前保持原版本", () => {
  let tempFile: string;

  beforeEach(() => {
    tempFile = join(tmpdir(), `bump-version-test-${Date.now()}.json`);
    writeFileSync(tempFile, JSON.stringify({ name: "test", version: "1.2.3" }, null, 2) + "\n");
  });

  afterEach(() => {
    if (existsSync(tempFile)) {
      unlinkSync(tempFile);
    }
  });

  test("set 无效版本不修改文件", () => {
    const original = readFileSync(tempFile, "utf-8");
    expect(() => bumpVersion("1.2.3", "set", "invalid")).toThrow();
    const after = readFileSync(tempFile, "utf-8");
    expect(after).toBe(original);
  });
});
