import { describe, expect, it, vi } from "vitest";
import { buildCopilotIdeHeaders } from "./copilot-dynamic-headers.js";
import {
  deriveCopilotApiBaseUrlFromToken,
  resolveCopilotApiToken,
} from "./github-copilot-token.js";

describe("resolveCopilotApiToken", () => {
  it("derives native Copilot base URLs from Copilot proxy hints", () => {
    expect(
      deriveCopilotApiBaseUrlFromToken(
        "copilot-token;proxy-ep=https://proxy.individual.githubcopilot.com;",
      ),
    ).toBe("https://api.individual.githubcopilot.com");
    expect(deriveCopilotApiBaseUrlFromToken("copilot-token;proxy-ep=proxy.example.com;")).toBe(
      "https://api.example.com",
    );
    expect(deriveCopilotApiBaseUrlFromToken("copilot-token;proxy-ep=proxy.example.com:8443;")).toBe(
      "https://api.example.com",
    );
  });

  it("rejects malformed or non-http proxy hints", () => {
    expect(
      deriveCopilotApiBaseUrlFromToken("copilot-token;proxy-ep=javascript:alert(1);"),
    ).toBeNull();
    expect(deriveCopilotApiBaseUrlFromToken("copilot-token;proxy-ep=://bad;")).toBeNull();
  });

  it("treats 11-digit expires_at values as seconds epochs", async () => {
    const fetchImpl = vi.fn(async () => ({
      ok: true,
      json: async () => ({
        token: "copilot-token",
        expires_at: 12_345_678_901,
      }),
    }));

    const result = await resolveCopilotApiToken({
      githubToken: "github-token",
      cachePath: "/tmp/github-copilot-token-test.json",
      loadJsonFileImpl: () => undefined,
      saveJsonFileImpl: () => undefined,
      fetchImpl: fetchImpl as unknown as typeof fetch,
    });

    expect(result.expiresAt).toBe(12_345_678_901_000);
  });

  it("sends IDE headers when exchanging the GitHub token", async () => {
    const fetchImpl = vi.fn(async () => ({
      ok: true,
      json: async () => ({
        token: "copilot-token",
        expires_at: Math.floor(Date.now() / 1000) + 3600,
      }),
    }));

    await resolveCopilotApiToken({
      githubToken: "github-token",
      cachePath: "/tmp/github-copilot-token-test.json",
      loadJsonFileImpl: () => undefined,
      saveJsonFileImpl: () => undefined,
      fetchImpl: fetchImpl as unknown as typeof fetch,
    });

    expect(fetchImpl).toHaveBeenCalledWith(
      "https://api.github.com/copilot_internal/v2/token",
      expect.objectContaining({
        method: "GET",
        headers: expect.objectContaining({
          Accept: "application/json",
          Authorization: "Bearer github-token",
          ...buildCopilotIdeHeaders({ includeApiVersion: true }),
        }),
      }),
    );
  });
});
