import { createHash } from "node:crypto";
export function hashString(value) {
    return createHash("sha256").update(value).digest("hex");
}
export function hashBytes(value) {
    return createHash("sha256").update(value).digest("hex");
}
export function hashJson(value) {
    return hashString(JSON.stringify(value));
}
export function normalizeContentForHash(content) {
    return content.replaceAll("\r\n", "\n").trim();
}
export function extractTaggedBlock(prompt, tag) {
    const open = `<${tag}>`;
    const close = `</${tag}>`;
    const start = prompt.indexOf(open);
    if (start === -1)
        return null;
    const end = prompt.indexOf(close, start + open.length);
    if (end === -1)
        return null;
    return prompt.slice(start + open.length, end).trim();
}
export function buildPromptHash(prompt) {
    const instructionsContent = extractTaggedBlock(prompt, "instructions");
    const contextContent = extractTaggedBlock(prompt, "context");
    // If at least one of the tags is present (even if empty), hash their contents.
    if (instructionsContent !== null || contextContent !== null) {
        const instructions = instructionsContent ?? "";
        const context = contextContent ?? "";
        return hashString(`${instructions}\n${context}`.trim());
    }
    // Fallback for prompts without any tags.
    return hashString(prompt.trim());
}
export function buildPromptContentHash({ prompt, fallbackContent, }) {
    const content = extractTaggedBlock(prompt, "content") ?? fallbackContent ?? null;
    if (!content || content.trim().length === 0)
        return null;
    return hashString(normalizeContentForHash(content));
}
export function buildAttachmentContentHash({ attachments, }) {
    if (attachments.length === 0)
        return null;
    return hashJson({
        attachments: attachments.map((attachment) => ({
            kind: attachment.kind,
            mediaType: attachment.mediaType.toLowerCase(),
            byteLength: attachment.bytes.byteLength,
            byteHash: hashBytes(attachment.bytes),
        })),
    });
}
export function buildLengthKey(lengthArg) {
    return lengthArg.kind === "preset"
        ? `preset:${lengthArg.preset}`
        : `chars:${lengthArg.maxCharacters}`;
}
export function buildLanguageKey(outputLanguage) {
    return outputLanguage.kind === "auto" ? "auto" : outputLanguage.tag;
}
export function buildExtractCacheKeyValue({ url, options, formatVersion, }) {
    return hashJson({ url, options, formatVersion });
}
export function buildSummaryCacheKeyValue({ contentHash, promptHash, model, lengthKey, languageKey, formatVersion, }) {
    return hashJson({
        contentHash,
        promptHash,
        model,
        lengthKey,
        languageKey,
        formatVersion,
    });
}
export function buildSlidesCacheKeyValue({ url, settings, formatVersion, }) {
    return hashJson({
        url,
        settings: {
            ocr: settings.ocr,
            outputDir: settings.outputDir,
            sceneThreshold: settings.sceneThreshold,
            autoTuneThreshold: settings.autoTuneThreshold,
            maxSlides: settings.maxSlides,
            minDurationSeconds: settings.minDurationSeconds,
        },
        formatVersion,
    });
}
export function buildTranscriptCacheKeyValue({ url, namespace, formatVersion, fileMtime, }) {
    return hashJson({
        url,
        namespace,
        fileMtime: fileMtime ?? null,
        formatVersion,
    });
}
//# sourceMappingURL=cache-keys.js.map