import { resolveRunOverrides } from "../run/run-settings.js";
import { resolveSlideSettings } from "../slides/index.js";
import { json, readJsonBody } from "./server-http.js";
export const SUMMARIZE_REQUEST_BODY_MAX_BYTES = 8_000_000;
export function parseDiagnostics(raw) {
    if (!raw || typeof raw !== "object") {
        return { includeContent: false };
    }
    const obj = raw;
    return { includeContent: Boolean(obj.includeContent) };
}
export function resolveHomeDir(env) {
    const home = env.HOME?.trim() || env.USERPROFILE?.trim();
    if (!home)
        return process.cwd();
    return home;
}
function resolveRequestSlidesSettings({ env, request, resolveToolPath, }) {
    const slidesValue = request.slides;
    const tesseractAvailable = resolveToolPath("tesseract", env, "TESSERACT_PATH") !== null;
    const slidesOcrValue = tesseractAvailable ? request.slidesOcr : false;
    return resolveSlideSettings({
        slides: slidesValue,
        slidesOcr: slidesOcrValue,
        // Daemon/API callers may be browser-extension or localhost clients that
        // only need to request extraction, not select host filesystem paths. Keep
        // slide artifacts under the per-user Summarize directory so an authenticated
        // request cannot write/delete slide files in arbitrary writable locations.
        slidesDir: ".summarize/slides",
        slidesSceneThreshold: request.slidesSceneThreshold,
        slidesSceneThresholdExplicit: typeof request.slidesSceneThreshold !== "undefined",
        slidesMax: request.slidesMax,
        slidesMinDuration: request.slidesMinDuration,
        cwd: resolveHomeDir(env),
    });
}
export async function parseSummarizeRequest({ req, res, cors, env, resolveToolPath, }) {
    let body;
    try {
        body = await readJsonBody(req, SUMMARIZE_REQUEST_BODY_MAX_BYTES);
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        json(res, 400, { ok: false, error: message }, cors);
        return null;
    }
    if (!body || typeof body !== "object") {
        json(res, 400, { ok: false, error: "invalid json" }, cors);
        return null;
    }
    const obj = body;
    const pageUrl = typeof obj.url === "string" ? obj.url.trim() : "";
    const title = typeof obj.title === "string" ? obj.title.trim() : null;
    const textContent = typeof obj.text === "string" ? obj.text : "";
    const truncated = Boolean(obj.truncated);
    const modelOverride = typeof obj.model === "string" ? obj.model.trim() : null;
    const lengthRaw = typeof obj.length === "string" ? obj.length.trim() : "";
    const languageRaw = typeof obj.language === "string" ? obj.language.trim() : "";
    const promptRaw = typeof obj.prompt === "string" ? obj.prompt : "";
    const promptOverride = promptRaw.trim() || null;
    const noCache = Boolean(obj.noCache);
    const extractOnly = Boolean(obj.extractOnly);
    const modeRaw = typeof obj.mode === "string" ? obj.mode.trim().toLowerCase() : "";
    const mode = modeRaw === "url" ? "url" : modeRaw === "page" ? "page" : "auto";
    const maxCharactersCandidate = typeof obj.maxExtractCharacters === "number" && Number.isFinite(obj.maxExtractCharacters)
        ? obj.maxExtractCharacters
        : typeof obj.maxCharacters === "number" && Number.isFinite(obj.maxCharacters)
            ? obj.maxCharacters
            : null;
    const maxCharacters = maxCharactersCandidate && maxCharactersCandidate > 0 ? maxCharactersCandidate : null;
    const formatRaw = typeof obj.format === "string" ? obj.format.trim().toLowerCase() : "";
    const format = formatRaw === "markdown" || formatRaw === "md" ? "markdown" : "text";
    const overrides = resolveRunOverrides(obj);
    const slidesSettings = resolveRequestSlidesSettings({ env, request: obj, resolveToolPath });
    const diagnostics = parseDiagnostics(obj.diagnostics);
    const hasText = Boolean(textContent.trim());
    if (!pageUrl || !/^https?:\/\//i.test(pageUrl)) {
        json(res, 400, { ok: false, error: "missing url" }, cors);
        return null;
    }
    if (extractOnly && mode === "page") {
        json(res, 400, { ok: false, error: "extractOnly requires mode=url" }, cors);
        return null;
    }
    if (mode === "page" && !hasText) {
        json(res, 400, { ok: false, error: "missing text" }, cors);
        return null;
    }
    return {
        pageUrl,
        title,
        textContent,
        truncated,
        modelOverride,
        lengthRaw,
        languageRaw,
        promptOverride,
        noCache,
        extractOnly,
        mode,
        maxCharacters,
        format,
        overrides,
        slidesSettings,
        diagnostics,
        hasText,
    };
}
//# sourceMappingURL=server-summarize-request.js.map