/**
 * CliVersion Component Tests
 *
 * Tests the version comparison logic used by the CliVersion component,
 * which compares the installed CLI version against the supported version.
 *
 * What this component does:
 * - Displays the installed Claude CLI version
 * - Displays the highest audited/supported CLI version
 * - Shows a warning when the installed version is ahead of or behind supported
 *
 * Manual testing checklist:
 * - [ ] Installed version is fetched and displayed on mount
 * - [ ] "current" badge shows in green when versions match
 * - [ ] "ahead" badge shows in amber when installed is newer than supported
 * - [ ] "behind" badge shows in red when installed is older than supported
 * - [ ] Warning message appears for "ahead" and "behind" states
 */

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

const SUPPORTED_CLI_VERSION = "2.1.53";

function compareVersions(a: string, b: string): number {
  const aParts = a.split(".").map(Number);
  const bParts = b.split(".").map(Number);
  for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
    const aVal = aParts[i] ?? 0;
    const bVal = bParts[i] ?? 0;
    if (aVal > bVal) return 1;
    if (aVal < bVal) return -1;
  }
  return 0;
}

// ---

describe("SUPPORTED_CLI_VERSION", () => {
  it("is defined and non-empty", () => {
    expect(SUPPORTED_CLI_VERSION).toBeTruthy();
  });

  it("matches the expected audited version", () => {
    expect(SUPPORTED_CLI_VERSION).toBe("2.1.53");
  });
});

describe("compareVersions", () => {
  describe("equal versions", () => {
    it("returns 0 for identical versions", () => {
      expect(compareVersions("1.0.0", "1.0.0")).toBe(0);
    });

    it("returns 0 for the supported CLI version against itself", () => {
      expect(compareVersions(SUPPORTED_CLI_VERSION, SUPPORTED_CLI_VERSION)).toBe(0);
    });

    it("returns 0 for 0.0.0 vs 0.0.0", () => {
      expect(compareVersions("0.0.0", "0.0.0")).toBe(0);
    });
  });

  describe("major version differences", () => {
    it("returns 1 when a has a higher major version", () => {
      expect(compareVersions("2.0.0", "1.0.0")).toBe(1);
    });

    it("returns -1 when a has a lower major version", () => {
      expect(compareVersions("1.0.0", "2.0.0")).toBe(-1);
    });
  });

  describe("minor version differences", () => {
    it("returns 1 when a has a higher minor version", () => {
      expect(compareVersions("1.2.0", "1.1.0")).toBe(1);
    });

    it("returns -1 when a has a lower minor version", () => {
      expect(compareVersions("1.1.0", "1.2.0")).toBe(-1);
    });
  });

  describe("patch version differences", () => {
    it("returns 1 when a has a higher patch version", () => {
      expect(compareVersions("1.0.2", "1.0.1")).toBe(1);
    });

    it("returns -1 when a has a lower patch version", () => {
      expect(compareVersions("1.0.1", "1.0.2")).toBe(-1);
    });
  });

  describe("major version takes precedence", () => {
    it("returns 1 when a has a higher major but lower minor", () => {
      expect(compareVersions("2.0.0", "1.9.9")).toBe(1);
    });

    it("returns -1 when a has a lower major but higher minor", () => {
      expect(compareVersions("1.9.9", "2.0.0")).toBe(-1);
    });
  });

  describe("unequal segment counts", () => {
    it("treats missing segments as 0 (a shorter than b)", () => {
      expect(compareVersions("1.0", "1.0.0")).toBe(0);
    });

    it("treats missing segments as 0 (a longer than b)", () => {
      expect(compareVersions("1.0.0", "1.0")).toBe(0);
    });

    it("correctly compares when a has an extra non-zero segment", () => {
      expect(compareVersions("1.0.1", "1.0")).toBe(1);
    });

    it("correctly compares when b has an extra non-zero segment", () => {
      expect(compareVersions("1.0", "1.0.1")).toBe(-1);
    });
  });

  describe("supported CLI version comparisons", () => {
    it("returns 1 for a version ahead of supported", () => {
      expect(compareVersions("2.2.0", SUPPORTED_CLI_VERSION)).toBe(1);
    });

    it("returns -1 for a version behind supported", () => {
      expect(compareVersions("2.1.0", SUPPORTED_CLI_VERSION)).toBe(-1);
    });

    it("returns 0 for exactly the supported version", () => {
      expect(compareVersions("2.1.53", SUPPORTED_CLI_VERSION)).toBe(0);
    });
  });
});
