import fs from 'node:fs/promises';
import path from 'node:path';
import { findCodexBinary } from '../codex-adapter.js';
import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
import { isRecord } from './codex-app-types.js';
export async function probeCodexAgentTypeSupport(root, input = {}) {
    const env = input.env || process.env;
    const fixture = await fixtureSchemaProbe(env);
    if (fixture)
        return persist(root, fixture, input.writeReport !== false);
    const schema = await readSchemaFromEnv(env);
    if (schema)
        return persist(root, probeSchema(schema.value, schema.source, schema.schemaPath), input.writeReport !== false);
    const doctor = await probeDoctorJson(input.codexBin, env);
    if (doctor.source !== 'unknown')
        return persist(root, doctor, input.writeReport !== false);
    const help = await probeHelp(input.codexBin, env);
    if (help.source !== 'unknown')
        return persist(root, help, input.writeReport !== false);
    const envProbe = envFallbackProbe(env);
    if (envProbe)
        return persist(root, envProbe, input.writeReport !== false);
    return persist(root, {
        schema: 'sks.codex-agent-type-probe.v1',
        generated_at: nowIso(),
        ok: true,
        supported: false,
        source: 'unknown',
        spawn_tool_name: 'unknown',
        schema_path: null,
        evidence: [],
        blockers: [],
        warnings: ['agent_type_support_unknown_message_role_fallback']
    }, input.writeReport !== false);
}
export function agentRolePayloadFor(role, probe) {
    if (probe.supported)
        return { strategy: 'agent_type', agent_type: role, probe_artifact_path: '.sneakoscope/reports/codex-agent-type-probe.json' };
    return {
        strategy: 'message-role',
        message_role_prefix: `Role: ${role}. Use this as a message-level role because native agent_type is unavailable or unverified.`,
        probe_artifact_path: '.sneakoscope/reports/codex-agent-type-probe.json'
    };
}
async function fixtureSchemaProbe(env) {
    const raw = env.SKS_CODEX_AGENT_TYPE_FIXTURE;
    if (!raw)
        return null;
    const supported = raw === '1' || raw === 'supported' || raw === 'true';
    return {
        schema: 'sks.codex-agent-type-probe.v1',
        generated_at: nowIso(),
        ok: true,
        supported,
        source: 'fixture',
        spawn_tool_name: supported ? 'spawn_agent' : 'unknown',
        schema_path: supported ? 'fixture.spawn_agent.parameters.agent_type' : null,
        evidence: [`fixture:${raw}`],
        blockers: [],
        warnings: []
    };
}
async function readSchemaFromEnv(env) {
    if (env.SKS_CODEX_TOOL_SCHEMA_FILE) {
        const file = path.resolve(env.SKS_CODEX_TOOL_SCHEMA_FILE);
        const text = await fs.readFile(file, 'utf8').catch(() => '');
        if (text)
            return { value: JSON.parse(text), source: 'codex-tool-schema', schemaPath: file };
    }
    if (env.SKS_CODEX_TOOL_SCHEMA_JSON) {
        return { value: JSON.parse(env.SKS_CODEX_TOOL_SCHEMA_JSON), source: 'codex-tool-schema', schemaPath: 'env:SKS_CODEX_TOOL_SCHEMA_JSON' };
    }
    return null;
}
async function probeDoctorJson(codexBin, env) {
    const bin = codexBin || env.CODEX_BIN || await findCodexBinary().catch(() => null);
    if (!bin)
        return unknownProbe(['codex_cli_missing']);
    const run = await runProcess(bin, ['doctor', '--json'], { env, timeoutMs: 8000, maxOutputBytes: 256 * 1024 }).catch(() => null);
    const text = `${run?.stdout || ''}${run?.stderr || ''}`.trim();
    if (!run || run.code !== 0 || !text)
        return unknownProbe(['codex_doctor_json_unavailable']);
    try {
        const parsed = JSON.parse(text);
        const probed = probeSchema(parsed, 'codex-doctor-json', 'doctor-json');
        return { ...probed, source: probed.supported ? 'codex-doctor-json' : 'unknown' };
    }
    catch {
        return unknownProbe(['codex_doctor_json_parse_failed']);
    }
}
async function probeHelp(codexBin, env) {
    const bin = codexBin || env.CODEX_BIN || await findCodexBinary().catch(() => null);
    if (!bin)
        return unknownProbe(['codex_cli_missing']);
    const run = await runProcess(bin, ['--help'], { env, timeoutMs: 5000, maxOutputBytes: 128 * 1024 }).catch(() => null);
    const text = `${run?.stdout || ''}${run?.stderr || ''}`;
    if (!run || run.code !== 0 || !text)
        return unknownProbe(['codex_help_unavailable']);
    const supported = /\bagent_type\b/.test(text) && /\bspawn_agent\b|\bmulti_agent_v2\b/.test(text);
    return {
        schema: 'sks.codex-agent-type-probe.v1',
        generated_at: nowIso(),
        ok: true,
        supported,
        source: supported ? 'codex-help' : 'unknown',
        spawn_tool_name: text.includes('multi_agent_v2') ? 'multi_agent_v2' : supported ? 'spawn_agent' : 'unknown',
        schema_path: supported ? 'codex --help' : null,
        evidence: supported ? ['help_mentions_agent_type'] : [],
        blockers: [],
        warnings: supported ? [] : ['agent_type_not_found_in_help']
    };
}
function envFallbackProbe(env) {
    if (env.SKS_CODEX_AGENT_TYPE_SUPPORTED === undefined)
        return null;
    if (env.SKS_CODEX_AGENT_TYPE_ALLOW_ENV_FALLBACK !== '1' && env.NODE_ENV !== 'test') {
        return {
            schema: 'sks.codex-agent-type-probe.v1',
            generated_at: nowIso(),
            ok: true,
            supported: false,
            source: 'env',
            spawn_tool_name: 'unknown',
            schema_path: null,
            evidence: [],
            blockers: [],
            warnings: ['env_agent_type_fallback_ignored_outside_test_mode']
        };
    }
    const supported = env.SKS_CODEX_AGENT_TYPE_SUPPORTED === '1';
    return {
        schema: 'sks.codex-agent-type-probe.v1',
        generated_at: nowIso(),
        ok: true,
        supported,
        source: 'env',
        spawn_tool_name: supported ? 'spawn_agent' : 'unknown',
        schema_path: supported ? 'env:SKS_CODEX_AGENT_TYPE_SUPPORTED' : null,
        evidence: [`env:SKS_CODEX_AGENT_TYPE_SUPPORTED=${env.SKS_CODEX_AGENT_TYPE_SUPPORTED}`],
        blockers: [],
        warnings: ['env_agent_type_fallback_test_only']
    };
}
function probeSchema(value, source, schemaPath) {
    const found = findAgentType(value);
    return {
        schema: 'sks.codex-agent-type-probe.v1',
        generated_at: nowIso(),
        ok: true,
        supported: found.supported,
        source,
        spawn_tool_name: found.tool,
        schema_path: found.path || schemaPath,
        evidence: found.supported ? [`agent_type:${found.path || 'found'}`] : ['agent_type_absent'],
        blockers: [],
        warnings: found.supported ? [] : ['agent_type_not_supported_message_role_fallback']
    };
}
function findAgentType(value, trail = []) {
    if (Array.isArray(value)) {
        for (let index = 0; index < value.length; index += 1) {
            const found = findAgentType(value[index], [...trail, String(index)]);
            if (found.supported)
                return found;
        }
        return { supported: false, tool: 'unknown', path: null };
    }
    if (!isRecord(value))
        return { supported: false, tool: 'unknown', path: null };
    const name = String(value.name || value.tool || value.id || '');
    const tool = name.includes('multi_agent_v2') ? 'multi_agent_v2' : name.includes('spawn_agent') ? 'spawn_agent' : 'unknown';
    if ('agent_type' in value || isRecord(value.properties) && 'agent_type' in value.properties) {
        return { supported: true, tool: tool === 'unknown' ? 'spawn_agent' : tool, path: [...trail, 'agent_type'].join('.') };
    }
    for (const [key, entry] of Object.entries(value)) {
        const found = findAgentType(entry, [...trail, key]);
        if (found.supported)
            return { ...found, tool: found.tool === 'unknown' && tool !== 'unknown' ? tool : found.tool };
    }
    return { supported: false, tool, path: null };
}
function unknownProbe(blockers) {
    return {
        schema: 'sks.codex-agent-type-probe.v1',
        generated_at: nowIso(),
        ok: blockers.length === 0,
        supported: false,
        source: 'unknown',
        spawn_tool_name: 'unknown',
        schema_path: null,
        evidence: [],
        blockers,
        warnings: ['agent_type_support_unknown_message_role_fallback']
    };
}
async function persist(root, report, writeReport) {
    if (writeReport)
        await writeJsonAtomic(path.join(root, '.sneakoscope', 'reports', 'codex-agent-type-probe.json'), report).catch(() => undefined);
    return report;
}
//# sourceMappingURL=codex-agent-type-probe.js.map