/**
 * OMK Provider Runner — DeepSeek-specific helpers
 * Extracted from provider-task-runner.ts to break God Module coupling
 */
import { DEEPSEEK_V4_FLASH_MODEL, DEEPSEEK_V4_PRO_MODEL } from "../router.js";
import { summarizeAdvisory } from "./results.js";
export function deepseekPlanFromNode(node) {
    if (!isDeepSeekLaneNode(node))
        return undefined;
    const model = [node.routing?.providerModel, node.routing?.assignedModel]
        .filter((value) => typeof value === "string")
        .join(" ")
        .toLowerCase();
    const tier = node.routing?.providerModelTier
        ?? (model.includes("pro") ? "pro" : model.includes("flash") ? "flash" : undefined);
    if (!tier)
        return undefined;
    return {
        provider: "deepseek",
        model: tier === "flash" ? DEEPSEEK_V4_FLASH_MODEL : DEEPSEEK_V4_PRO_MODEL,
        tier,
        participation: "direct",
        reasoningEffort: "max",
        ratioBucket: tier === "flash" ? 0 : 9,
    };
}
function isDeepSeekLaneNode(node) {
    return node.routing?.provider === "deepseek" || node.routing?.providerModel?.toLowerCase().includes("deepseek") || false;
}
export function sleepWithAbort(ms, signal) {
    return new Promise((resolve, reject) => {
        if (signal?.aborted) {
            reject(signal.reason ?? new Error("Aborted"));
            return;
        }
        const timer = setTimeout(resolve, ms);
        signal?.addEventListener("abort", () => {
            clearTimeout(timer);
            reject(signal.reason ?? new Error("Aborted"));
        }, { once: true });
    });
}
export function resolveDeepSeekAdvisoryTimeoutMs(env = process.env) {
    const raw = env.OMK_DEEPSEEK_ADVISORY_TIMEOUT_MS;
    if (!raw)
        return 30_000;
    const parsed = Number(raw);
    return Number.isFinite(parsed) && parsed > 0 ? parsed : 30_000;
}
export function parseStructuredAdvisory(stdout) {
    const result = { summary: "", suggestions: [], confidence: 0 };
    try {
        const json = JSON.parse(stdout);
        if (json && typeof json === "object") {
            const obj = json;
            if (typeof obj.summary === "string")
                result.summary = obj.summary;
            if (Array.isArray(obj.suggestions))
                result.suggestions = obj.suggestions.filter((s) => typeof s === "string");
            if (Array.isArray(obj.findings))
                result.findings = obj.findings.filter((s) => typeof s === "string");
            if (Array.isArray(obj.risks))
                result.risks = obj.risks.filter((s) => typeof s === "string");
            if (Array.isArray(obj.questionsForAuthorityProvider)) {
                result.questionsForAuthorityProvider = obj.questionsForAuthorityProvider.filter((s) => typeof s === "string");
            }
            if (typeof obj.confidence === "number")
                result.confidence = obj.confidence;
        }
    }
    catch {
        // Fallback: treat entire stdout as summary
        result.summary = stdout.trim();
    }
    return result;
}
export async function runDeepSeekAdvisory(options) {
    let result;
    const controller = new AbortController();
    const forwardAbort = () => {
        controller.abort(options.signal?.reason ?? new Error("Aborted"));
    };
    if (options.signal?.aborted)
        forwardAbort();
    else
        options.signal?.addEventListener("abort", forwardAbort, { once: true });
    const timeoutMs = resolveDeepSeekAdvisoryTimeoutMs({ ...process.env, ...options.env });
    let timeout;
    try {
        const runPromise = options.runner.run(options.node, {
            ...options.env,
            ...options.traceEnv,
            OMK_DEEPSEEK_MODEL: options.plan.model,
            OMK_DEEPSEEK_MODEL_TIER: options.plan.tier,
            OMK_DEEPSEEK_PARTICIPATION: options.plan.participation,
            OMK_PROVIDER: "deepseek",
            OMK_PROVIDER_REQUESTED: "deepseek",
            OMK_PROVIDER_ROUTE_REASON: options.routeReason,
            OMK_PROVIDER_AUTHORITY: "advisory",
        }, controller.signal, options.context);
        const timeoutPromise = new Promise((resolve) => {
            timeout = setTimeout(() => {
                const reason = new Error(`DeepSeek advisory timed out after ${timeoutMs}ms`);
                controller.abort(reason);
                resolve({ success: false, exitCode: 124, stdout: "", stderr: reason.message });
            }, timeoutMs);
        });
        result = await Promise.race([runPromise, timeoutPromise]);
    }
    catch (error) {
        result = { success: false, exitCode: 1, stdout: "", stderr: String(error) };
    }
    finally {
        if (timeout)
            clearTimeout(timeout);
        options.signal?.removeEventListener("abort", forwardAbort);
    }
    const success = result.success;
    const structured = success ? parseStructuredAdvisory(result.stdout) : undefined;
    const summary = structured?.summary ?? (success ? summarizeAdvisory(result.stdout) : "");
    const failureReason = success ? undefined : summarizeFailures([result]);
    return {
        success,
        result,
        summary,
        failureReason,
        structured,
        metadata: {
            provider: "deepseek",
            model: options.plan.model,
            modelTier: options.plan.tier,
            participation: "advisory",
            invocationKey: options.invocationKey,
            success,
            summary,
            failureReason,
        },
    };
}
function summarizeFailures(failures) {
    if (failures.length === 0)
        return "";
    return failures
        .map((failure, index) => {
        const text = `${failure.stderr}\n${failure.stdout}`.trim().replace(/\s+/g, " ");
        return `attempt ${index + 1}: ${text || `exit ${failure.exitCode ?? "unknown"}`}`;
    })
        .join(" | ")
        .slice(0, 500);
}
