import { isMediaInputFailure } from "@/lib/ai/runtime/request-failure-classification"; function parseUrl(value: string) { try { return new URL(String(value || "").trim()); } catch { return null; } } export function isUrlWithinPublicBase(mediaUrl: string, publicBaseUrl: string) { const media = parseUrl(mediaUrl); const base = parseUrl(publicBaseUrl); if (!media || !base || media.host.toLowerCase() !== base.host.toLowerCase()) { return false; } const basePath = base.pathname.replace(/\/+$/, ""); if (!basePath) return true; return media.pathname === basePath || media.pathname.startsWith(`${basePath}/`); } export function shouldStageVip98kReferenceUrl(params: { mediaUrl: string; sourcePublicUrl: string; targetPublicUrl?: string; }) { if ( params.targetPublicUrl && isUrlWithinPublicBase(params.mediaUrl, params.targetPublicUrl) ) { return false; } return isUrlWithinPublicBase(params.mediaUrl, params.sourcePublicUrl); } export function getStorageObjectKeyFromPublicUrl( mediaUrl: string, publicBaseUrl: string, ) { if (!isUrlWithinPublicBase(mediaUrl, publicBaseUrl)) return null; const media = parseUrl(mediaUrl); const base = parseUrl(publicBaseUrl); if (!media || !base) return null; const basePath = base.pathname.replace(/\/+$/, ""); const encodedKey = media.pathname.slice(basePath.length).replace(/^\/+/, ""); if (!encodedKey) return null; try { return decodeURIComponent(encodedKey); } catch { return encodedKey; } } export function getVip98kStagedMediaRetryDelay(params: { status: number; message: string; attempt: number; maxAttempts: number; stagedReferenceCount: number; }) { if ( params.status !== 400 || params.stagedReferenceCount < 1 || params.attempt >= params.maxAttempts || !isMediaInputFailure(params.message) ) { return null; } return params.attempt * 20_000; } export function getVip98kSubmissionRetryDelay(params: { status: number; message: string; attempt: number; maxAttempts: number; retryAfterMs?: number | null; }) { if ( params.status !== 503 || params.attempt >= params.maxAttempts || !/pending\s+safe\s+reconciliation/i.test(params.message) ) { return null; } const providerDelay = Number(params.retryAfterMs); if (Number.isFinite(providerDelay) && providerDelay > 0) { return Math.min(Math.max(providerDelay, 1_000), 60_000); } return Math.min(params.attempt * 15_000, 30_000); } export function addVip98kReferenceRetryToken(mediaUrl: string, token: string) { const parsed = parseUrl(mediaUrl); if (!parsed) return mediaUrl; parsed.searchParams.set("sg_media_retry", token); return parsed.toString(); }