import { repairFindMeta } from '../../conversion/shared/tooling.js';
import { normalizeExecCommandArgs } from '../../tools/exec-command/normalize.js';
function isObject(v) {
    return !!v && typeof v === 'object' && !Array.isArray(v);
}
function packShellCommand(cmd) {
    // Normalize into ["bash","-lc","<single string>"] to support pipes, parens, -exec, etc.
    const normalizeArray = (argv) => {
        if (argv.length >= 2 && argv[0].toLowerCase() === 'bash' && argv[1] === '-lc') {
            if (argv.length === 3)
                return ['bash', '-lc', repairFindMeta(String(argv[2]))];
            const tail = argv.slice(2).join(' ');
            return ['bash', '-lc', repairFindMeta(tail)];
        }
        const joined = argv.join(' ');
        return ['bash', '-lc', repairFindMeta(joined)];
    };
    try {
        if (Array.isArray(cmd)) {
            return normalizeArray(cmd.map((x) => String(x)));
        }
        if (typeof cmd === 'string') {
            // If the string looks like a JSON array, attempt to parse before normalizing.
            const trimmed = cmd.trim();
            if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
                try {
                    const parsed = JSON.parse(trimmed);
                    if (Array.isArray(parsed)) {
                        return normalizeArray(parsed.map((x) => String(x)));
                    }
                }
                catch {
                    // fall back to treating as plain string
                }
            }
            return ['bash', '-lc', repairFindMeta(cmd)];
        }
    }
    catch {
        // fall through
    }
    return cmd;
}
/**
 * Ensure choices[*].message.tool_calls[].function.arguments is a JSON string.
 */
export class ResponseToolArgumentsStringifyFilter {
    name = 'response_tool_arguments_stringify';
    stage = 'response_post';
    apply(input) {
        try {
            const out = JSON.parse(JSON.stringify(input || {}));
            const choices = Array.isArray(out.choices) ? out.choices : [];
            for (const ch of choices) {
                const msg = ch && ch.message ? ch.message : undefined;
                const tcs = msg && Array.isArray(msg.tool_calls) ? msg.tool_calls : [];
                for (const tc of tcs) {
                    try {
                        const fn = tc && tc.function ? tc.function : undefined;
                        if (fn && typeof fn === 'object') {
                            const name = typeof fn.name === 'string' ? String(fn.name).trim().toLowerCase() : '';
                            const argIn = fn.arguments;
                            let parsed = undefined;
                            if (typeof argIn === 'string') {
                                try {
                                    parsed = JSON.parse(argIn);
                                }
                                catch {
                                    parsed = undefined;
                                }
                            }
                            else if (isObject(argIn)) {
                                parsed = argIn;
                            }
                            if (name === 'shell' && isObject(parsed)) {
                                const cmd = parsed.command;
                                parsed.command = packShellCommand(cmd);
                                try {
                                    fn.arguments = JSON.stringify(parsed ?? {});
                                }
                                catch {
                                    fn.arguments = '{}';
                                }
                            }
                            else if (name === 'exec_command' && isObject(parsed)) {
                                const normalized = normalizeExecCommandArgs(parsed);
                                const next = normalized.ok ? normalized.normalized : parsed;
                                try {
                                    fn.arguments = JSON.stringify(next ?? {});
                                }
                                catch {
                                    fn.arguments = '{}';
                                }
                            }
                            else if ((name === 'shell_command' || name === 'bash') && isObject(parsed)) {
                                try {
                                    fn.arguments = JSON.stringify(parsed ?? {});
                                }
                                catch {
                                    fn.arguments = '{}';
                                }
                            }
                            else {
                                if (typeof argIn !== 'string') {
                                    try {
                                        fn.arguments = JSON.stringify(argIn ?? {});
                                    }
                                    catch {
                                        fn.arguments = '{}';
                                    }
                                }
                            }
                            // Ensure invariants per tool_call
                            if (!tc.id || typeof tc.id !== 'string') {
                                const basis = `${name || 'tool'}_${Math.random().toString(36).slice(2, 10)}`;
                                tc.id = `call_${basis}`;
                            }
                            if (!tc.type)
                                tc.type = 'function';
                        }
                    }
                    catch { /* ignore */ }
                }
            }
            out.choices = choices;
            return { ok: true, data: out };
        }
        catch {
            return { ok: true, data: input };
        }
    }
}
