import { createLogger } from "../../../src/utils/logger/index.js";
import { init_logger } from "../../../src/utils/logger.js";
import { pickTimeoutMsOrFallback } from "../../../src/media-shared/http/deadline.js";
import { privateNetworkPolicyToSsrfGuardOptions } from "../../../src/media-shared/http/private-network.js";
import { resolveProviderHttpRequestConfig } from "../../../src/media-shared/http/resolve-provider-http-request-config.js";
import { postJsonRequest } from "../../../src/media-shared/http/provider-http.js";
import "../../../src/media-shared/http/index.js";
import { imageFileExtensionForMimeType } from "../../../src/agent/image/generation/image-assets.js";
import { resolveApiKeyForProvider } from "../../../src/providers/auth-runtime/resolve-api-key.js";
import { isProviderApiKeyConfigured } from "../../../src/providers/auth-runtime/is-configured.js";
import "../../../src/providers/auth-runtime/index.js";
//#region extensions/google/src/image-generation-provider.ts
/**
* Bundled Google Gemini image-generation provider.
*
* Uses the Gemini `generateContent` REST surface
* (`https://generativelanguage.googleapis.com/v1beta/models/<model>:generateContent`)
* with `responseModalities: ['TEXT', 'IMAGE']`, accepting Buffer-encoded
* `inlineData` parts back. Supports both text-to-image (no inputImages) and
* image-editing (one or more inputImages, sent as additional inlineData parts).
*
* Authentication: prefers `?key=<API_KEY>` query (the canonical Gemini surface);
* falls back to `Authorization: Bearer` when the user explicitly configures an
* OAuth-style key. Configure via env `GOOGLE_API_KEY` /
* `GEMINI_API_KEY` / `GENERATIVE_LANGUAGE_API_KEY`, or via
* `cfg.providers.google.apiKey`.
*/
init_logger();
const log = createLogger("ImageGen:Google");
const DEFAULT_GEMINI_BASE_URL = "https://generativelanguage.googleapis.com";
const GOOGLE_IMAGE_UI = {
	baseUrlPresets: [{
		value: DEFAULT_GEMINI_BASE_URL,
		label: "Google AI (default)"
	}],
	baseUrlPresetKind: "google"
};
const DEFAULT_GEMINI_API_VERSION = "v1beta";
const DEFAULT_TIMEOUT_MS = 18e4;
/** Gemini image-capable model ids for this extension. */
const GOOGLE_IMAGE_MODELS = [
	"gemini-2.5-flash-image-preview",
	"gemini-3-pro-image-preview",
	"gemini-3-flash-image-preview"
];
const GOOGLE_DEFAULT_IMAGE_MODEL = GOOGLE_IMAGE_MODELS[0];
const GOOGLE_CAPABILITIES = {
	generate: {
		maxCount: 4,
		supportsSize: true,
		supportsAspectRatio: true
	},
	edit: {
		enabled: true,
		maxInputImages: 5,
		supportsSize: true,
		supportsAspectRatio: true
	},
	geometry: {
		sizes: [
			"1024x1024",
			"1024x1536",
			"1536x1024",
			"1024x1792",
			"1792x1024"
		],
		aspectRatios: [
			"1:1",
			"2:3",
			"3:2",
			"3:4",
			"4:3",
			"4:5",
			"5:4",
			"9:16",
			"16:9",
			"21:9"
		]
	},
	output: { formats: [
		"png",
		"jpeg",
		"webp"
	] }
};
function readGoogleCfgString(cfg, key) {
	const providers = cfg?.providers;
	if (!providers || typeof providers !== "object") return void 0;
	const entry = providers["google"];
	if (!entry || typeof entry !== "object") return void 0;
	const v = entry[key];
	return typeof v === "string" && v.trim() ? v.trim() : void 0;
}
/**
* Resolve Google Gemini base URL precedence:
* 1. cfg.providers.google.baseUrl
* 2. GEMINI_BASE_URL / GOOGLE_GENERATIVE_AI_BASE_URL env
* 3. Default https://generativelanguage.googleapis.com
*/
function resolveGoogleBaseUrl(req) {
	const fromCfg = readGoogleCfgString(req.cfg, "baseUrl");
	if (fromCfg) return fromCfg.replace(/\/+$/, "");
	const fromEnv = (process.env.GEMINI_BASE_URL ?? process.env.GOOGLE_GENERATIVE_AI_BASE_URL)?.trim();
	if (fromEnv) return fromEnv.replace(/\/+$/, "");
	return DEFAULT_GEMINI_BASE_URL;
}
function resolveGoogleApiVersion(req) {
	const fromCfg = readGoogleCfgString(req.cfg, "apiVersion");
	if (fromCfg) return fromCfg;
	const fromEnv = process.env.GEMINI_API_VERSION?.trim();
	if (fromEnv) return fromEnv;
	return DEFAULT_GEMINI_API_VERSION;
}
function resolveGoogleAuthMode(req) {
	const v = (readGoogleCfgString(req.cfg, "authMode") ?? process.env.GEMINI_AUTH_MODE ?? "").trim().toLowerCase();
	if (v === "bearer" || v === "oauth") return "bearer";
	return "query";
}
function extractInlineData(part) {
	if (part && typeof part === "object") {
		if ("inlineData" in part && part.inlineData) return part.inlineData;
		if ("inline_data" in part && part.inline_data) return part.inline_data;
	}
}
async function generateGoogleImages(params) {
	const { req, apiKey } = params;
	const model = req.model?.trim() || GOOGLE_DEFAULT_IMAGE_MODEL;
	const apiVersion = resolveGoogleApiVersion(req);
	const baseUrl = resolveGoogleBaseUrl(req);
	const authMode = resolveGoogleAuthMode(req);
	const userParts = [{ text: req.prompt }];
	for (const image of req.inputImages ?? []) {
		const mimeType = image.mimeType?.trim() || "image/png";
		userParts.push({ inlineData: {
			mimeType,
			data: Buffer.from(image.buffer).toString("base64")
		} });
	}
	const generationConfig = { responseModalities: ["TEXT", "IMAGE"] };
	const imageConfig = {};
	if (req.aspectRatio?.trim()) imageConfig.aspectRatio = req.aspectRatio.trim();
	if (req.size?.trim()) imageConfig.size = req.size.trim();
	if (req.outputFormat?.trim()) imageConfig.outputFormat = req.outputFormat.trim();
	if (Object.keys(imageConfig).length > 0) generationConfig.imageConfig = imageConfig;
	const candidateCount = Math.max(1, Math.min(4, req.count ?? 1));
	if (candidateCount > 1) generationConfig.candidateCount = candidateCount;
	const body = {
		contents: [{
			role: "user",
			parts: userParts
		}],
		generationConfig
	};
	const baseEndpoint = `${baseUrl}/${apiVersion}/models/${encodeURIComponent(model)}:generateContent`;
	const url = authMode === "query" ? `${baseEndpoint}?key=${encodeURIComponent(apiKey)}` : baseEndpoint;
	const httpDefaults = resolveProviderHttpRequestConfig({
		providerId: "google",
		cfg: req.cfg,
		fallbackTimeoutMs: DEFAULT_TIMEOUT_MS
	});
	const headers = { ...httpDefaults.headers };
	if (authMode === "bearer") headers.authorization = `Bearer ${apiKey}`;
	log.debug({
		providerId: "google",
		model,
		url: baseEndpoint,
		authMode,
		candidateCount,
		inputImages: (req.inputImages ?? []).length,
		phase: "request"
	}, "Google Gemini image generation request");
	const rawText = await (await postJsonRequest(url, {
		label: "google",
		timeoutMs: pickTimeoutMsOrFallback(req.timeoutMs, httpDefaults.timeoutMs, DEFAULT_TIMEOUT_MS),
		signal: req.signal,
		body,
		headers,
		...privateNetworkPolicyToSsrfGuardOptions()
	})).text();
	let data;
	try {
		data = JSON.parse(rawText);
	} catch {
		throw new Error(`Google Gemini returned non-JSON: ${rawText.slice(0, 240)}`);
	}
	if (data.error) {
		const code = data.error.code ?? data.error.status ?? "UNKNOWN";
		throw new Error(`Google Gemini: ${code}: ${data.error.message ?? "request failed"}`);
	}
	if (data.promptFeedback?.blockReason) throw new Error(`Google Gemini blocked prompt: ${data.promptFeedback.blockReason}`);
	const collected = [];
	let index = 0;
	for (const candidate of data.candidates ?? []) for (const part of candidate.content?.parts ?? []) {
		const inline = extractInlineData(part);
		if (!inline?.data) continue;
		const mimeType = inline.mimeType?.trim() || "image/png";
		const buffer = Buffer.from(inline.data, "base64");
		if (buffer.length === 0) continue;
		index += 1;
		const ext = imageFileExtensionForMimeType(mimeType);
		collected.push({
			buffer,
			mimeType,
			fileName: `image-${index}.${ext}`
		});
	}
	if (collected.length === 0) {
		const finishReason = data.candidates?.[0]?.finishReason ?? "unknown";
		throw new Error(`Google Gemini returned no image data (finishReason=${finishReason}). Verify the model id supports image output.`);
	}
	return {
		images: collected,
		model
	};
}
function buildGoogleImageGenerationProvider() {
	return {
		id: "google",
		aliases: ["gemini"],
		label: "Google Gemini",
		defaultModel: GOOGLE_DEFAULT_IMAGE_MODEL,
		models: [...GOOGLE_IMAGE_MODELS],
		capabilities: GOOGLE_CAPABILITIES,
		ui: GOOGLE_IMAGE_UI,
		isConfigured: (ctx) => isProviderApiKeyConfigured({
			providerId: "google",
			cfg: ctx.cfg
		}),
		async generateImage(req) {
			const apiKey = resolveApiKeyForProvider({
				providerId: "google",
				cfg: req.cfg
			});
			if (!apiKey) throw new Error("Google Gemini API key missing (set GOOGLE_API_KEY / GEMINI_API_KEY or providers.google.apiKey)");
			return generateGoogleImages({
				req,
				apiKey
			});
		}
	};
}
//#endregion
export { GOOGLE_DEFAULT_IMAGE_MODEL, GOOGLE_IMAGE_MODELS, buildGoogleImageGenerationProvider, generateGoogleImages, resolveGoogleBaseUrl };

//# sourceMappingURL=image-generation-provider.js.map