import { resolveClosestAspectRatio, resolveClosestResolution, resolveClosestSize } from "../../media-generation/runtime-shared.js";
import "../../media-generation/index.js";
//#region src/agent/image/generation/normalization.ts
/**
* Image-generation parameter normalization.
*
* Reconciles user-supplied geometry / output overrides against the active
* provider's declared {@link ImageGenerationProviderCapabilities}. Returns:
*   - the actually-applied values to forward to the provider
*   - per-field {@link MediaNormalizationEntry} (requested / applied / derivedFrom)
*   - a list of {@link ImageGenerationIgnoredOverride} entries for unsupported
*     soft fields (so the LLM / UI can surface a Note)
*
* Hard errors (unsupported edit, too many input images) are thrown so the
* caller can fail fast — they are NOT downgraded to ignored overrides.
*
* Decision table — see docs/image-generation-rearchitecture.md §6.3
*/
function resolveImageGenerationOverrides(params) {
	const provider = params.provider;
	const caps = provider.capabilities ?? {};
	const isEdit = (params.inputImages?.length ?? 0) > 0;
	assertEditSupported(provider, isEdit, params.inputImages);
	const modeCaps = isEdit ? caps.edit : caps.generate;
	const supportsSize = modeCaps?.supportsSize === true;
	const supportsAspectRatio = modeCaps?.supportsAspectRatio === true;
	const supportsResolution = caps.generate?.supportsResolution === true && !isEdit;
	const ignoredOverrides = [];
	const normalization = {};
	const { size, aspectRatio, resolution } = resolveGeometry({
		requestedSize: params.size,
		requestedAspectRatio: params.aspectRatio,
		requestedResolution: params.resolution,
		supportsSize,
		supportsAspectRatio,
		supportsResolution,
		geometry: caps.geometry,
		ignoredOverrides,
		normalization
	});
	const quality = filterEnumOverride({
		key: "quality",
		requested: params.quality,
		supported: caps.output?.qualities,
		ignoredOverrides
	});
	const outputFormat = filterEnumOverride({
		key: "outputFormat",
		requested: params.outputFormat,
		supported: caps.output?.formats,
		ignoredOverrides
	});
	const background = filterEnumOverride({
		key: "background",
		requested: params.background,
		supported: caps.output?.backgrounds,
		ignoredOverrides
	});
	return {
		...size !== void 0 ? { size } : {},
		...aspectRatio !== void 0 ? { aspectRatio } : {},
		...resolution !== void 0 ? { resolution } : {},
		...quality !== void 0 ? { quality } : {},
		...outputFormat !== void 0 ? { outputFormat } : {},
		...background !== void 0 ? { background } : {},
		ignoredOverrides,
		...hasAnyEntry(normalization) ? { normalization } : {}
	};
}
function resolveGeometry(params) {
	const supportedSizes = params.geometry?.sizes;
	const supportedAspectRatios = params.geometry?.aspectRatios;
	const supportedResolutions = params.geometry?.resolutions;
	let size;
	let aspectRatio;
	let resolution;
	if (params.requestedSize) if (params.supportsSize) {
		const applied = resolveClosestSize({
			requestedSize: params.requestedSize,
			supportedSizes
		});
		if (applied) {
			size = applied;
			params.normalization.size = entry({
				requested: params.requestedSize,
				applied,
				supportedValues: supportedSizes
			});
		} else size = params.requestedSize;
	} else if (params.supportsAspectRatio) {
		const derived = resolveClosestAspectRatio({
			requestedSize: params.requestedSize,
			supportedAspectRatios
		});
		if (derived) {
			aspectRatio = derived;
			params.normalization.aspectRatio = entry({
				applied: derived,
				derivedFrom: "size",
				supportedValues: supportedAspectRatios
			});
		} else ignored(params.ignoredOverrides, "size", params.requestedSize);
	} else ignored(params.ignoredOverrides, "size", params.requestedSize);
	if (params.requestedAspectRatio) {
		if (params.supportsAspectRatio) {
			const finalApplied = resolveClosestAspectRatio({
				requestedAspectRatio: params.requestedAspectRatio,
				supportedAspectRatios
			}) ?? params.requestedAspectRatio;
			aspectRatio = finalApplied;
			params.normalization.aspectRatio = entry({
				requested: params.requestedAspectRatio,
				applied: finalApplied,
				supportedValues: supportedAspectRatios
			});
		} else if (params.supportsSize && size === void 0) {
			const derived = resolveClosestSize({
				requestedAspectRatio: params.requestedAspectRatio,
				supportedSizes
			});
			if (derived) {
				size = derived;
				params.normalization.size = entry({
					applied: derived,
					derivedFrom: "aspectRatio",
					supportedValues: supportedSizes
				});
			} else ignored(params.ignoredOverrides, "aspectRatio", params.requestedAspectRatio);
		} else if (!params.supportsSize) ignored(params.ignoredOverrides, "aspectRatio", params.requestedAspectRatio);
		if (!params.supportsAspectRatio && params.supportsSize && size !== void 0 && params.normalization.size?.derivedFrom !== "aspectRatio") ignored(params.ignoredOverrides, "aspectRatio", params.requestedAspectRatio);
	}
	if (params.requestedResolution) if (params.supportsResolution) {
		const finalApplied = resolveClosestResolution({
			requestedResolution: params.requestedResolution,
			supportedResolutions
		}) ?? params.requestedResolution;
		resolution = finalApplied;
		params.normalization.resolution = entry({
			requested: params.requestedResolution,
			applied: finalApplied,
			supportedValues: supportedResolutions
		});
	} else ignored(params.ignoredOverrides, "resolution", params.requestedResolution);
	return {
		size,
		aspectRatio,
		resolution
	};
}
function assertEditSupported(provider, isEdit, inputImages) {
	if (!isEdit) return;
	const editCap = (provider.capabilities ?? {}).edit;
	if (!(editCap?.enabled === true)) throw new Error(`${provider.id} image editing is not supported.`);
	const max = editCap.maxInputImages;
	if (typeof max === "number" && (inputImages?.length ?? 0) > max) throw new Error(`${provider.id} accepts at most ${max} input image(s); got ${inputImages?.length ?? 0}.`);
}
function filterEnumOverride(params) {
	if (params.requested === void 0) return void 0;
	if (!params.supported || params.supported.length === 0) return params.requested;
	if (params.supported.includes(params.requested)) return params.requested;
	ignored(params.ignoredOverrides, params.key, params.requested);
}
function ignored(list, key, value) {
	list.push({
		key,
		value
	});
}
function entry(init) {
	return {
		...init.requested !== void 0 ? { requested: init.requested } : {},
		...init.applied !== void 0 ? { applied: init.applied } : {},
		...init.derivedFrom !== void 0 ? { derivedFrom: init.derivedFrom } : {},
		...init.supportedValues ? { supportedValues: [...init.supportedValues] } : {}
	};
}
function hasAnyEntry(n) {
	return n.size !== void 0 || n.aspectRatio !== void 0 || n.resolution !== void 0;
}
//#endregion
export { resolveImageGenerationOverrides };

//# sourceMappingURL=normalization.js.map