import assert from "node:assert/strict";
import { describe, test, vi } from "vitest";
import type { Context, Model } from "../types.js";

const geminiCliCore = vi.hoisted(() => ({
	retryError: undefined as Error | undefined,
	retryOptions: undefined as Record<string, unknown> | undefined,
	helperArgs: undefined as Record<string, unknown> | undefined,
}));

vi.mock("@google/gemini-cli-core", () => ({
	CodeAssistServer: class {
		async generateContentStream(): Promise<AsyncGenerator<unknown>> {
			return (async function* emptyStream() {})();
		}
	},
	retryWithBackoff: vi.fn(
		async (_fn: unknown, options: Record<string, unknown>) => {
			geminiCliCore.retryOptions = options;
			throw geminiCliCore.retryError ?? new Error("quota exhausted");
		},
	),
}));

vi.mock("@singularity-forge/google-gemini-cli-provider", () => ({
	createGeminiCliContentGenerator: vi.fn(
		async (args: Record<string, unknown>) => {
			geminiCliCore.helperArgs = args;
			return {
				async generateContentStream(): Promise<AsyncGenerator<unknown>> {
					return (async function* emptyStream() {})();
				},
			};
		},
	),
}));

import { streamGoogleGeminiCli } from "./google-gemini-cli.js";

function makeModel(): Model<"google-gemini-cli"> {
	return {
		id: "gemini-3-flash-preview",
		name: "Gemini 3 Flash Preview",
		api: "google-gemini-cli",
		provider: "google-gemini-cli",
		baseUrl: "",
		reasoning: true,
		input: ["text"],
		cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
		contextWindow: 1_000_000,
		maxTokens: 8192,
	};
}

function makeContext(): Context {
	return {
		messages: [{ role: "user", content: "hello", timestamp: 0 }],
	};
}

describe("google-gemini-cli provider retry ownership", () => {
	test("google_gemini_cli_when_quota_resets_soon_returns_error_to_caller_without_cli_retry_loop", async () => {
		geminiCliCore.retryOptions = undefined;
		geminiCliCore.retryError = Object.assign(
			new Error(
				"You have exhausted your capacity on this model. Your quota will reset after 54s.",
			),
			{ retryDelayMs: 54_000 },
		);

		const stream = streamGoogleGeminiCli(makeModel(), makeContext());
		const result = await stream.result();

		const retryOptions = geminiCliCore.retryOptions as
			| { maxAttempts?: unknown }
			| undefined;
		assert.equal(retryOptions?.maxAttempts, 1);
		assert.equal(geminiCliCore.helperArgs?.modelId, "gemini-3-flash-preview");
		assert.equal(result.stopReason, "error");
		assert.match(result.errorMessage ?? "", /exhausted your capacity/i);
		assert.equal(result.retryAfterMs, 54_000);
	});
});
