/**
 * google-gemini-token-counter.js — Google Gemini CLI token counting
 *
 * Purpose: provider-specific token counting for Gemini CLI payloads using the
 * CodeAssist server API. Isolated from the generic token-counter so that
 * Gemini-only imports (@google/gemini-cli-core, google-auth-library) are
 * not loaded for users who never use Gemini.
 *
 * Consumer: bootstrap/register-hooks.js token-count hook.
 */

/**
 * Parse Google Gemini CLI API key JSON to extract token and project ID.
 */
export function parseGoogleGeminiCliApiKey(apiKeyRaw) {
	try {
		const parsed = JSON.parse(apiKeyRaw);
		if (
			typeof parsed.token !== "string" ||
			typeof parsed.projectId !== "string"
		) {
			return undefined;
		}
		if (!parsed.token || !parsed.projectId) {
			return undefined;
		}
		return { token: parsed.token, projectId: parsed.projectId };
	} catch {
		return undefined;
	}
}

async function buildGoogleGeminiCliServer(apiKeyRaw) {
	const credentials = parseGoogleGeminiCliApiKey(apiKeyRaw);
	if (!credentials) {
		throw new Error("Invalid Google Gemini CLI credentials");
	}
	const [{ CodeAssistServer }, { OAuth2Client }] = await Promise.all([
		import("@google/gemini-cli-core"),
		import("google-auth-library"),
	]);
	const authClient = new OAuth2Client();
	authClient.setCredentials({ access_token: credentials.token });
	return new CodeAssistServer(authClient, credentials.projectId, {
		headers: {},
	});
}

/**
 * Type guard for Google Gemini token counting payload.
 */
export function isGoogleGeminiCountablePayload(payload) {
	if (!payload || typeof payload !== "object") return false;
	const candidate = payload;
	return (
		typeof candidate.model === "string" && Array.isArray(candidate.contents)
	);
}

/**
 * Count tokens in a Google Gemini CLI request using their server API.
 */
export async function countGoogleGeminiCliTokens(
	payload,
	apiKeyRaw,
	deps = { buildServer: buildGoogleGeminiCliServer },
) {
	if (!apiKeyRaw || !isGoogleGeminiCountablePayload(payload)) return undefined;
	const response = await (await deps.buildServer(apiKeyRaw)).countTokens(
		payload,
	);
	return typeof response.totalTokens === "number"
		? response.totalTokens
		: undefined;
}
