import { failNativeRequired, isNativeDisabledByEnv } from './native-router-hotpath-policy.js';
import { loadNativeRouterHotpathBindingForInternalUse } from './native-router-hotpath.js';
function readNativeFunction(name) {
    const binding = loadNativeRouterHotpathBindingForInternalUse();
    const fn = binding?.[name];
    return typeof fn === 'function' ? fn : null;
}
function safeStringify(value) {
    try {
        return JSON.stringify(value);
    }
    catch {
        return undefined;
    }
}
function parseRecord(raw) {
    try {
        const parsed = JSON.parse(raw);
        if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
            return null;
        }
        return parsed;
    }
    catch {
        return null;
    }
}
function parseOptionalRecord(raw) {
    try {
        const parsed = JSON.parse(raw);
        if (parsed === null) {
            return undefined;
        }
        if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
            return null;
        }
        return parsed;
    }
    catch {
        return null;
    }
}
function parseStyle(raw) {
    try {
        const parsed = JSON.parse(raw);
        if (parsed === null || parsed === undefined) {
            return undefined;
        }
        if (typeof parsed !== 'string') {
            return null;
        }
        const normalized = parsed.trim().toLowerCase();
        if (normalized === 'fc' || normalized === 'preserve') {
            return normalized;
        }
        return null;
    }
    catch {
        return null;
    }
}
function parseToolOutputEntry(raw) {
    if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
        return null;
    }
    const row = raw;
    const toolCallId = (typeof row.tool_call_id === 'string' && row.tool_call_id.trim()) ||
        (typeof row.toolCallId === 'string' && row.toolCallId.trim()) ||
        (typeof row.call_id === 'string' && row.call_id.trim()) ||
        (typeof row.callId === 'string' && row.callId.trim()) ||
        '';
    const callId = (typeof row.call_id === 'string' && row.call_id.trim()) ||
        (typeof row.callId === 'string' && row.callId.trim()) ||
        (typeof row.tool_call_id === 'string' && row.tool_call_id.trim()) ||
        (typeof row.toolCallId === 'string' && row.toolCallId.trim()) ||
        '';
    if (!toolCallId || !callId) {
        return null;
    }
    const outputRaw = row.output;
    let output;
    if (typeof outputRaw === 'string') {
        output = outputRaw;
    }
    else if (outputRaw !== undefined) {
        try {
            output = JSON.stringify(outputRaw);
        }
        catch {
            output = String(outputRaw);
        }
    }
    const name = typeof row.name === 'string' && row.name.trim() ? row.name.trim() : undefined;
    return {
        tool_call_id: toolCallId,
        call_id: callId,
        ...(output !== undefined ? { output } : {}),
        ...(name ? { name } : {})
    };
}
function parseResumeToolOutputs(raw) {
    try {
        const parsed = JSON.parse(raw);
        if (!Array.isArray(parsed)) {
            return null;
        }
        const out = [];
        for (const entry of parsed) {
            if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
                continue;
            }
            const row = entry;
            const toolCallId = (typeof row.tool_call_id === 'string' && row.tool_call_id.trim()) ||
                (typeof row.toolCallId === 'string' && row.toolCallId.trim()) ||
                '';
            if (!toolCallId || typeof row.content !== 'string') {
                continue;
            }
            out.push({ tool_call_id: toolCallId, content: row.content });
        }
        return out;
    }
    catch {
        return null;
    }
}
function parseCollectedToolOutputs(raw) {
    try {
        const parsed = JSON.parse(raw);
        if (!Array.isArray(parsed)) {
            return null;
        }
        const out = [];
        for (const entry of parsed) {
            const normalized = parseToolOutputEntry(entry);
            if (normalized) {
                out.push(normalized);
            }
        }
        return out;
    }
    catch {
        return null;
    }
}
function parseMergedToolOutputs(raw) {
    try {
        const parsed = JSON.parse(raw);
        if (parsed === null) {
            return undefined;
        }
        if (!Array.isArray(parsed)) {
            return null;
        }
        const out = [];
        for (const entry of parsed) {
            if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
                continue;
            }
            const row = entry;
            const toolCallId = (typeof row.tool_call_id === 'string' && row.tool_call_id.trim()) ||
                (typeof row.toolCallId === 'string' && row.toolCallId.trim()) ||
                '';
            if (!toolCallId || typeof row.content !== 'string') {
                continue;
            }
            const name = typeof row.name === 'string' && row.name.trim() ? row.name.trim() : undefined;
            out.push({ tool_call_id: toolCallId, content: row.content, ...(name ? { name } : {}) });
        }
        return out;
    }
    catch {
        return null;
    }
}
function parseNormalizedTools(raw) {
    try {
        const parsed = JSON.parse(raw);
        if (parsed === null) {
            return undefined;
        }
        if (!Array.isArray(parsed)) {
            return null;
        }
        return parsed;
    }
    catch {
        return null;
    }
}
function parseOptionalString(raw) {
    try {
        const parsed = JSON.parse(raw);
        if (parsed === null) {
            return undefined;
        }
        if (typeof parsed !== 'string') {
            return null;
        }
        const trimmed = parsed.trim();
        return trimmed ? trimmed : undefined;
    }
    catch {
        return null;
    }
}
export function mapResumeToolOutputsDetailedWithNative(responsesResume) {
    const capability = 'mapResumeToolOutputsDetailedJson';
    const fail = (reason) => failNativeRequired(capability, reason);
    if (isNativeDisabledByEnv()) {
        return fail('native disabled');
    }
    const fn = readNativeFunction('mapResumeToolOutputsDetailedJson');
    if (!fn) {
        return fail();
    }
    const payloadJson = safeStringify(responsesResume ?? null);
    if (!payloadJson) {
        return fail('json stringify failed');
    }
    try {
        const raw = fn(payloadJson);
        if (typeof raw !== 'string' || !raw) {
            return fail('empty result');
        }
        const parsed = parseResumeToolOutputs(raw);
        return parsed ?? fail('invalid payload');
    }
    catch (error) {
        const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
        return fail(reason);
    }
}
export function resolveServerToolFollowupSnapshotWithNative(adapterContext) {
    const capability = 'resolveServerToolFollowupSnapshotJson';
    const fail = (reason) => failNativeRequired(capability, reason);
    if (isNativeDisabledByEnv()) {
        return fail('native disabled');
    }
    const fn = readNativeFunction('resolveServerToolFollowupSnapshotJson');
    if (!fn) {
        return fail();
    }
    const payloadJson = safeStringify(adapterContext ?? null);
    if (!payloadJson) {
        return fail('json stringify failed');
    }
    try {
        const raw = fn(payloadJson);
        if (typeof raw !== 'string' || !raw) {
            return fail('empty result');
        }
        const parsed = parseOptionalRecord(raw);
        return parsed === null ? fail('invalid payload') : parsed;
    }
    catch (error) {
        const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
        return fail(reason);
    }
}
export function augmentContextSnapshotWithNative(context, fallbackSnapshot) {
    const capability = 'augmentContextSnapshotJson';
    const fail = (reason) => failNativeRequired(capability, reason);
    if (isNativeDisabledByEnv()) {
        return fail('native disabled');
    }
    const fn = readNativeFunction('augmentContextSnapshotJson');
    if (!fn) {
        return fail();
    }
    const contextJson = safeStringify(context);
    const fallbackJson = safeStringify(fallbackSnapshot);
    if (!contextJson || !fallbackJson) {
        return fail('json stringify failed');
    }
    try {
        const raw = fn(contextJson, fallbackJson);
        if (typeof raw !== 'string' || !raw) {
            return fail('empty result');
        }
        const parsed = parseRecord(raw);
        return parsed ?? fail('invalid payload');
    }
    catch (error) {
        const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
        return fail(reason);
    }
}
export function normalizeToolCallIdStyleCandidateWithNative(value) {
    const capability = 'normalizeToolCallIdStyleCandidateJson';
    const fail = (reason) => failNativeRequired(capability, reason);
    if (isNativeDisabledByEnv()) {
        return fail('native disabled');
    }
    const fn = readNativeFunction('normalizeToolCallIdStyleCandidateJson');
    if (!fn) {
        return fail();
    }
    const payloadJson = safeStringify(value ?? null);
    if (!payloadJson) {
        return fail('json stringify failed');
    }
    try {
        const raw = fn(payloadJson);
        if (typeof raw !== 'string' || !raw) {
            return fail('empty result');
        }
        const parsed = parseStyle(raw);
        return parsed === null ? fail('invalid payload') : parsed;
    }
    catch (error) {
        const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
        return fail(reason);
    }
}
export function collectToolOutputsWithNative(payload) {
    const capability = 'collectToolOutputsJson';
    const fail = (reason) => failNativeRequired(capability, reason);
    if (isNativeDisabledByEnv()) {
        return fail('native disabled');
    }
    const fn = readNativeFunction('collectToolOutputsJson');
    if (!fn) {
        return fail();
    }
    const payloadJson = safeStringify(payload ?? null);
    if (!payloadJson) {
        return fail('json stringify failed');
    }
    try {
        const raw = fn(payloadJson);
        if (typeof raw !== 'string' || !raw) {
            return fail('empty result');
        }
        const parsed = parseCollectedToolOutputs(raw);
        return parsed ?? fail('invalid payload');
    }
    catch (error) {
        const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
        return fail(reason);
    }
}
export function mergeContextToolOutputsWithNative(existing, snapshot) {
    const capability = 'mergeContextToolOutputsJson';
    const fail = (reason) => failNativeRequired(capability, reason);
    if (isNativeDisabledByEnv()) {
        return fail('native disabled');
    }
    const fn = readNativeFunction('mergeContextToolOutputsJson');
    if (!fn) {
        return fail();
    }
    const existingJson = safeStringify(existing ?? null);
    const snapshotJson = safeStringify(snapshot);
    if (!existingJson || !snapshotJson) {
        return fail('json stringify failed');
    }
    try {
        const raw = fn(existingJson, snapshotJson);
        if (typeof raw !== 'string' || !raw) {
            return fail('empty result');
        }
        const parsed = parseMergedToolOutputs(raw);
        return parsed === null ? fail('invalid payload') : parsed;
    }
    catch (error) {
        const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
        return fail(reason);
    }
}
export function normalizeContextToolsWithNative(snapshot) {
    const capability = 'normalizeContextToolsJson';
    const fail = (reason) => failNativeRequired(capability, reason);
    if (isNativeDisabledByEnv()) {
        return fail('native disabled');
    }
    const fn = readNativeFunction('normalizeContextToolsJson');
    if (!fn) {
        return fail();
    }
    const snapshotJson = safeStringify(snapshot);
    if (!snapshotJson) {
        return fail('json stringify failed');
    }
    try {
        const raw = fn(snapshotJson);
        if (typeof raw !== 'string' || !raw) {
            return fail('empty result');
        }
        const parsed = parseNormalizedTools(raw);
        return parsed === null ? fail('invalid payload') : parsed;
    }
    catch (error) {
        const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
        return fail(reason);
    }
}
export function selectToolCallIdStyleWithNative(adapterContext, snapshot, current) {
    const capability = 'selectToolCallIdStyleJson';
    const fail = (reason) => failNativeRequired(capability, reason);
    if (isNativeDisabledByEnv()) {
        return fail('native disabled');
    }
    const fn = readNativeFunction('selectToolCallIdStyleJson');
    if (!fn) {
        return fail();
    }
    const adapterContextJson = safeStringify(adapterContext);
    const snapshotJson = safeStringify(snapshot);
    const currentJson = safeStringify(current ?? null);
    if (!adapterContextJson || !snapshotJson || !currentJson) {
        return fail('json stringify failed');
    }
    try {
        const raw = fn(adapterContextJson, snapshotJson, currentJson);
        if (typeof raw !== 'string' || !raw) {
            return fail('empty result');
        }
        const parsed = parseStyle(raw);
        return parsed === null ? fail('invalid payload') : parsed;
    }
    catch (error) {
        const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
        return fail(reason);
    }
}
