import assert from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
import {
  enqueueGoogleGenerate,
  googleRequestGapMs,
  resolveGoogleModel,
} from "../GoogleGenAiAdapter.ts";

describe("resolveGoogleModel", () => {
  it("returns explicit gemini model ids unchanged", () => {
    assert.equal(resolveGoogleModel("gemini-2.5-flash"), "gemini-2.5-flash");
  });

  it("falls back when model is default/auto", () => {
    assert.equal(
      resolveGoogleModel("default", "gemini-2.5-flash"),
      "gemini-2.5-flash",
    );
    assert.equal(
      resolveGoogleModel(undefined, "gemini-2.5-flash"),
      "gemini-2.5-flash",
    );
  });

  it("throws when opaque and no fallback", () => {
    assert.throws(
      () => resolveGoogleModel("default"),
      /requires an explicit Gemini model id/,
    );
  });

  it("rejects non-gemini explicit ids", () => {
    assert.throws(
      () => resolveGoogleModel("gpt-4o"),
      /must be a Gemini model id/,
    );
  });

  it("remaps deprecated gemini-2.0-flash to gemini-3.5-flash", () => {
    assert.equal(resolveGoogleModel("gemini-2.0-flash"), "gemini-3.5-flash");
  });
});

describe("Google generate queue", () => {
  const prevGap = process.env.CODEFLOW_GOOGLE_REQUEST_GAP_MS;

  afterEach(() => {
    if (prevGap === undefined) delete process.env.CODEFLOW_GOOGLE_REQUEST_GAP_MS;
    else process.env.CODEFLOW_GOOGLE_REQUEST_GAP_MS = prevGap;
  });

  it("allows configuring request gap including zero", () => {
    process.env.CODEFLOW_GOOGLE_REQUEST_GAP_MS = "0";
    assert.equal(googleRequestGapMs(), 0);
    process.env.CODEFLOW_GOOGLE_REQUEST_GAP_MS = "125";
    assert.equal(googleRequestGapMs(), 125);
  });

  it("serializes concurrent Gemini stream tasks", async () => {
    process.env.CODEFLOW_GOOGLE_REQUEST_GAP_MS = "0";
    const events: string[] = [];

    const first = enqueueGoogleGenerate(async () => {
      events.push("first:start");
      await new Promise((resolve) => setTimeout(resolve, 20));
      events.push("first:end");
      return "first";
    });
    const second = enqueueGoogleGenerate(async () => {
      events.push("second:start");
      events.push("second:end");
      return "second";
    });

    assert.deepEqual(await Promise.all([first, second]), ["first", "second"]);
    assert.deepEqual(events, [
      "first:start",
      "first:end",
      "second:start",
      "second:end",
    ]);
  });
});
