import { repairFindMeta } from '../../conversion/shared/tooling.js';
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
const asNonEmptyString = (value) => {
    if (typeof value !== 'string')
        return undefined;
    const trimmed = value.trim();
    return trimmed ? trimmed : undefined;
};
const asPrimitiveString = (value) => {
    if (typeof value === 'string')
        return asNonEmptyString(value);
    if (typeof value === 'number' && Number.isFinite(value))
        return String(value);
    if (typeof value === 'boolean')
        return String(value);
    return undefined;
};
const asFiniteNumber = (value) => {
    if (typeof value !== 'number' || !Number.isFinite(value))
        return undefined;
    return value;
};
const asBoolean = (value) => {
    if (typeof value !== 'boolean')
        return undefined;
    return value;
};
const asStringArray = (value) => {
    if (!Array.isArray(value))
        return undefined;
    const out = [];
    for (const entry of value) {
        if (typeof entry === 'string') {
            out.push(entry);
            continue;
        }
        if (entry == null)
            continue;
        out.push(String(entry));
    }
    return out.length ? out : undefined;
};
/**
 * Normalize Codex CLI exec_command arguments (shape fixes only):
 * - accept cmd/command/toon as sources for cmd
 * - drop "toon" (must never be exposed to client)
 * - repair common `find -exec ... ;` meta issues in cmd
 */
export function normalizeExecCommandArgs(args) {
    const base = isRecord(args) ? { ...args } : {};
    const cmdCandidate = asPrimitiveString(base.cmd) ??
        asPrimitiveString(base.command) ??
        asPrimitiveString(base.toon) ??
        asPrimitiveString(base.script) ??
        (() => {
            const arr = asStringArray(base.command) ?? asStringArray(base.cmd);
            return arr ? arr.join(' ') : undefined;
        })();
    // Always drop toon from outward-facing args (even if used as cmd source).
    try {
        if (Object.prototype.hasOwnProperty.call(base, 'toon')) {
            delete base.toon;
        }
    }
    catch {
        // ignore
    }
    if (!cmdCandidate) {
        // Keep captured samples free of hidden TOON payloads.
        try {
            if (Object.prototype.hasOwnProperty.call(base, 'toon')) {
                delete base.toon;
            }
        }
        catch {
            // ignore
        }
        return { ok: false, reason: 'missing_cmd', normalized: base };
    }
    const fixedCmd = repairFindMeta(cmdCandidate);
    const normalized = { cmd: fixedCmd };
    const workdir = asNonEmptyString(base.workdir) ??
        asNonEmptyString(base.cwd) ??
        asNonEmptyString(base.workDir);
    if (workdir)
        normalized.workdir = workdir;
    const login = asBoolean(base.login);
    if (login !== undefined)
        normalized.login = login;
    const tty = asBoolean(base.tty);
    if (tty !== undefined)
        normalized.tty = tty;
    const timeoutMs = asFiniteNumber(base.timeout_ms) ??
        asFiniteNumber(base.timeoutMs);
    if (timeoutMs !== undefined)
        normalized.timeout_ms = timeoutMs;
    const shell = asNonEmptyString(base.shell);
    if (shell)
        normalized.shell = shell;
    const sandboxPermissions = asNonEmptyString(base.sandbox_permissions) ??
        (asBoolean(base.with_escalated_permissions) ? 'require_escalated' : undefined);
    if (sandboxPermissions)
        normalized.sandbox_permissions = sandboxPermissions;
    const justification = asNonEmptyString(base.justification);
    if (justification)
        normalized.justification = justification;
    const maxOutput = asFiniteNumber(base.max_output_tokens) ?? asFiniteNumber(base.max_tokens);
    if (maxOutput !== undefined)
        normalized.max_output_tokens = maxOutput;
    const yieldTime = asFiniteNumber(base.yield_time_ms) ??
        asFiniteNumber(base.yield_ms) ??
        asFiniteNumber(base.wait_ms);
    if (yieldTime !== undefined)
        normalized.yield_time_ms = yieldTime;
    return { ok: true, normalized };
}
