import { ALLOWED_EXTERNAL_IMAGE_MIME_TYPES, MAX_EXTERNAL_IMAGE_BYTES } from "./image-security-constants.js";
import { BlockedExternalUnsupportedBytesError, BlockedInlineImageExceedingError, BlockedInlineUnsupportedBytesError, InvalidInlineImageMalformedBase64Error } from "./image-security-errors.js";
import { fileTypeFromBuffer } from "file-type";

//#region src/domains/run/services/blob-storage/image-content-security.ts
async function normalizeInlineImageBytes(file) {
	const data = decodeBase64ImageBytes(file.bytes);
	validateInlineImageSize(data);
	const sniffedMime = await sniffAllowedImageMimeType(data);
	if (sniffedMime) return {
		data,
		mimeType: sniffedMime
	};
	throw new BlockedInlineUnsupportedBytesError(file.mimeType || "unknown");
}
async function resolveDownloadedImageMimeType(data, headerContentType) {
	const sniffedMime = await sniffAllowedImageMimeType(data);
	if (sniffedMime) return sniffedMime;
	throw new BlockedExternalUnsupportedBytesError(headerContentType || "unknown");
}
function validateInlineImageSize(data) {
	if (data.length > MAX_EXTERNAL_IMAGE_BYTES) throw new BlockedInlineImageExceedingError(MAX_EXTERNAL_IMAGE_BYTES);
}
async function sniffAllowedImageMimeType(data) {
	const sniffedMime = (await fileTypeFromBuffer(data))?.mime?.toLowerCase();
	if (sniffedMime && ALLOWED_EXTERNAL_IMAGE_MIME_TYPES.has(sniffedMime)) return sniffedMime;
	return null;
}
function decodeBase64ImageBytes(base64Bytes) {
	const normalized = base64Bytes.replace(/\s+/g, "");
	if (normalized.length === 0 || normalized.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(normalized)) throw new InvalidInlineImageMalformedBase64Error();
	const decoded = Buffer.from(normalized, "base64");
	if (decoded.length === 0 || decoded.toString("base64") !== normalized) throw new InvalidInlineImageMalformedBase64Error();
	return Uint8Array.from(decoded);
}

//#endregion
export { normalizeInlineImageBytes, resolveDownloadedImageMimeType };