import path from 'node:path';
import { findCodexBinary } from '../codex-adapter.js';
import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
export async function detectCodex0139Capability(input = {}) {
    const fake = process.env.SKS_CODEX_0139_FAKE === '1';
    const codexBin = fake
        ? input.codexBin || process.env.CODEX_BIN || 'codex'
        : input.codexBin || process.env.CODEX_BIN || await findCodexBinary();
    const versionText = fake
        ? String(process.env.SKS_CODEX_VERSION_FAKE || 'codex-cli 0.139.0')
        : await readCodexVersionText(codexBin);
    const parsed = parseCodexVersionText(versionText);
    const atLeast139 = Boolean(parsed && compareSemverLike(parsed, '0.139.0') >= 0);
    const probeMode = process.env.SKS_CODEX_0139_PROBE === '1' ? 'feature-probe' : 'version-only';
    const featureProbeResults = probeMode === 'feature-probe'
        ? await probeCodex0139Features(codexBin, { fake })
        : {
            marketplace_list_json: 'skipped',
            sandbox_profile_alias: 'skipped'
        };
    const marketplaceOk = atLeast139 && (probeMode === 'version-only' || featureProbeResults.marketplace_list_json !== 'failed');
    const profileAliasOk = atLeast139 && (probeMode === 'version-only' || featureProbeResults.sandbox_profile_alias !== 'failed');
    const blockers = [
        ...(!codexBin ? ['codex_cli_missing'] : []),
        ...(atLeast139 ? [] : ['codex_0_139_required_for_search_schema_marketplace_features']),
        ...(probeMode === 'feature-probe' && featureProbeResults.marketplace_list_json === 'failed' ? ['codex_marketplace_list_json_probe_failed'] : [])
    ];
    return {
        schema: 'sks.codex-0139-capability.v1',
        ok: atLeast139 && blockers.length === 0,
        probe_mode: probeMode,
        codex_bin: codexBin || null,
        version_text: versionText || null,
        parsed_version: parsed,
        supports_code_mode_web_search: atLeast139,
        supports_rich_tool_schemas: atLeast139,
        supports_doctor_env_details: atLeast139,
        supports_marketplace_source_field: marketplaceOk,
        supports_plugin_catalog_cache: atLeast139,
        supports_sandbox_profile_alias: profileAliasOk,
        supports_interrupt_agent_rename: atLeast139,
        feature_probe_results: featureProbeResults,
        blockers
    };
}
export async function writeCodex0139CapabilityArtifacts(root, input = {}) {
    const capability = await detectCodex0139Capability({ codexBin: input.codexBin || null });
    const report = { ...capability, generated_at: nowIso() };
    const rootArtifact = path.join(root, '.sneakoscope', 'codex-0139-capability.json');
    await writeJsonAtomic(rootArtifact, report);
    let missionArtifact = null;
    if (input.missionId) {
        missionArtifact = path.join(root, '.sneakoscope', 'missions', input.missionId, 'codex-0139-capability.json');
        await writeJsonAtomic(missionArtifact, report);
    }
    return { report, root_artifact: rootArtifact, mission_artifact: missionArtifact };
}
async function readCodexVersionText(codexBin) {
    if (!codexBin)
        return null;
    const result = await runProcess(codexBin, ['--version'], { timeoutMs: 10_000, maxOutputBytes: 16 * 1024 }).catch((err) => ({
        code: 1,
        stdout: '',
        stderr: err?.message || String(err)
    }));
    const text = `${result.stdout || ''}${result.stderr || ''}`.trim();
    return result.code === 0 ? text : text || null;
}
async function probeCodex0139Features(codexBin, opts = {}) {
    if (opts.fake) {
        return {
            marketplace_list_json: process.env.SKS_CODEX_0139_FAKE_MARKETPLACE_FAIL === '1' ? 'failed' : 'passed',
            sandbox_profile_alias: 'passed'
        };
    }
    const timeoutMs = Math.max(1, Number(process.env.SKS_CODEX_0139_PROBE_TIMEOUT_MS || 3000) || 3000);
    if (!codexBin) {
        return { marketplace_list_json: 'failed', sandbox_profile_alias: 'failed' };
    }
    const marketplace = await runProcess(codexBin, ['plugin', 'marketplace', 'list', '--json'], { timeoutMs, maxOutputBytes: 256 * 1024 }).catch(() => ({ code: 1, stdout: '' }));
    const marketplaceListJson = marketplace.code === 0 && marketplaceSourcesPresent(marketplace.stdout) ? 'passed' : 'failed';
    const help = await runProcess(codexBin, ['--help'], { timeoutMs, maxOutputBytes: 256 * 1024 }).catch(() => ({ code: 1, stdout: '' }));
    const aliasOk = help.code === 0 && /(^|\s)-P[,\s]/m.test(String(help.stdout || ''));
    return {
        marketplace_list_json: marketplaceListJson,
        sandbox_profile_alias: aliasOk ? 'passed' : 'failed'
    };
}
export function marketplaceSourcesPresent(stdout) {
    try {
        const parsed = JSON.parse(String(stdout || ''));
        const rows = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.marketplaces) ? parsed.marketplaces : Array.isArray(parsed?.items) ? parsed.items : [];
        if (!rows.length)
            return true;
        return rows.some((row) => typeof row?.source === 'string' && row.source.length > 0);
    }
    catch {
        return false;
    }
}
//# sourceMappingURL=codex-0139-capability.js.map