import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { isDirectMediaExtension, isDirectMediaUrl, isDirectVideoInput, } from "@steipete/summarize-core/content/url";
import mime from "mime";
import { classifyUrl, loadLocalAsset, loadRemoteAsset, shouldProbeUnknownAssetUrl, } from "../content/asset.js";
import { assertAssetMediaTypeSupported } from "../run/attachments.js";
function normalizePathForExtension(value) {
    try {
        return new URL(value).pathname;
    }
    catch {
        return value.split(/[?#]/, 1)[0];
    }
}
export function isTranscribableAssetPath(value) {
    if (isDirectMediaUrl(value))
        return true;
    const ext = path.extname(normalizePathForExtension(value));
    return isDirectMediaExtension(ext);
}
export function isPdfAssetPath(value) {
    return path.extname(normalizePathForExtension(value)).toLowerCase() === ".pdf";
}
function isTranscribableMediaType(mediaType) {
    const normalized = mediaType.toLowerCase();
    return normalized.startsWith("audio/") || normalized.startsWith("video/");
}
function createMediaInput({ sourceKind, sourceLabel, filename, sizeBytes, }) {
    return {
        kind: "resolved-media",
        sourceKind,
        sourceLabel,
        attachment: {
            kind: "file",
            filename,
            mediaType: "audio/mpeg",
            bytes: new Uint8Array(0),
        },
        sizeBytes,
    };
}
export async function getLocalAssetSize(filePath) {
    return await fs
        .stat(filePath)
        .then((stat) => (stat.isFile() ? stat.size : null))
        .catch(() => null);
}
export async function acquireLocalAssetInput({ filePath, maxBytes, }) {
    if (isTranscribableAssetPath(filePath)) {
        const sizeBytes = await getLocalAssetSize(filePath);
        return createMediaInput({
            sourceKind: "file",
            sourceLabel: filePath,
            filename: path.basename(filePath),
            sizeBytes,
        });
    }
    const loaded = await loadLocalAsset({ filePath, maxBytes });
    assertAssetMediaTypeSupported({ attachment: loaded.attachment, sizeLabel: null });
    return {
        kind: isTranscribableMediaType(loaded.attachment.mediaType)
            ? "resolved-media"
            : "resolved-asset",
        sourceKind: "file",
        sourceLabel: loaded.sourceLabel,
        attachment: loaded.attachment,
        sizeBytes: loaded.attachment.bytes.byteLength,
    };
}
export async function resolveUrlAssetRoute({ url, isYoutubeUrl, fetchImpl, timeoutMs, detectUnknownAssetUrls = true, assumeAsset = false, }) {
    if (!url || isYoutubeUrl)
        return "none";
    if (isTranscribableAssetPath(url))
        return isDirectVideoInput(url) ? "video" : "audio";
    if (!detectUnknownAssetUrls && !shouldProbeUnknownAssetUrl(url)) {
        return assumeAsset ? "asset" : "none";
    }
    const kind = await classifyUrl({ url, fetchImpl, timeoutMs });
    if (kind.kind === "media")
        return kind.mediaType.startsWith("video/") ? "video" : "audio";
    if (kind.kind === "asset")
        return "asset";
    return assumeAsset ? "asset" : "none";
}
export function createRemoteMediaInput(url) {
    let filename = "media";
    try {
        filename = path.basename(new URL(url).pathname) || filename;
    }
    catch {
        // Keep the stable fallback name.
    }
    return createMediaInput({
        sourceKind: "asset-url",
        sourceLabel: url,
        filename,
        sizeBytes: null,
    });
}
export async function acquireRemoteAssetInput({ url, fetchImpl, timeoutMs, }) {
    const loaded = await (async () => {
        try {
            return await loadRemoteAsset({ url, fetchImpl, timeoutMs });
        }
        catch (error) {
            if (error instanceof Error && /HTML/i.test(error.message)) {
                return null;
            }
            throw error;
        }
    })();
    if (!loaded)
        return null;
    assertAssetMediaTypeSupported({ attachment: loaded.attachment, sizeLabel: null });
    return {
        kind: isTranscribableMediaType(loaded.attachment.mediaType)
            ? "resolved-media"
            : "resolved-asset",
        sourceKind: "asset-url",
        sourceLabel: loaded.sourceLabel,
        attachment: loaded.attachment,
        sizeBytes: loaded.attachment.bytes.byteLength,
    };
}
export async function materializeAcquiredMediaInput(input) {
    const extension = mime.getExtension(input.attachment.mediaType);
    const rawFilename = path.basename(input.attachment.filename?.trim() || "media");
    const filename = path.extname(rawFilename) || !extension ? rawFilename : `${rawFilename}.${extension}`;
    const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "summarize-media-"));
    const filePath = path.join(tempDir, filename);
    const cleanup = async () => {
        await fs.rm(tempDir, { recursive: true, force: true }).catch(() => { });
    };
    try {
        await fs.writeFile(filePath, input.attachment.bytes, {
            mode: 0o600,
            flag: "wx",
        });
    }
    catch (error) {
        await cleanup();
        throw error;
    }
    return { filePath, cleanup };
}
//# sourceMappingURL=input-acquisition.js.map