"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
/*
 * Story 3.8 — OPENLIFE_RUNTIME_PROFILE=oauth-only regression test.
 *
 * Hardens the previously undocumented "oauth-only" runtime profile defined in
 * `src/cli/WorldClassCommands.ts` (`doctorWorldDetailed()`). The profile is a
 * pure SEVERITY CLASSIFIER — it downgrades four specific doctor checks from
 * `blocker` to `info` when the operator runs OAuth-authenticated LLM CLIs
 * (`claude`, `codex`, `gemini`) instead of API keys. It does NOT alter the
 * Brain.ts provider chain.
 *
 * Asserts (4 scenarios):
 *   a) Default profile (no env var) — failing oauth-downgrade names come back
 *      with their non-`info` default severity (cli:ollama → blocker; the three
 *      env:*_API_KEY → warning). In short: NONE of the four is `info`.
 *   b) `oauth-only` set — failing names of cli:ollama / env:OPENAI_API_KEY /
 *      env:GEMINI_API_KEY / env:ANTHROPIC_API_KEY all come back as `info`.
 *   c) Case-insensitive — `OAuth-Only` triggers the same downgrade
 *      (the classifier calls `.toLowerCase()`).
 *   d) Other failing checks are unaffected — e.g. `cli:codex`, `cli:claude`,
 *      `runtime:*` stay non-`info` even with oauth-only profile.
 *
 * Test seams used (per project convention — production code is strict):
 *   - process.chdir(tempDir) because WorldClassCommands reads process.cwd().
 *   - Mutate process.env directly and restore in finally.
 */
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
function assert(cond, msg) {
    if (!cond)
        throw new Error(`ASSERTION_FAILED: ${msg}`);
}
const OAUTH_DOWNGRADE_NAMES = [
    'cli:ollama',
    'env:OPENAI_API_KEY',
    'env:GEMINI_API_KEY',
    'env:ANTHROPIC_API_KEY'
];
function makeTempDir(label) {
    const dir = fs.mkdtempSync(path.join(os.tmpdir(), `openlife-oauth-only-${label}-`));
    return dir;
}
const PROBE_KEYS = [
    'OPENLIFE_RUNTIME_PROFILE',
    'OPENLIFE_ENABLE_OLLAMA',
    'OPENAI_API_KEY',
    'GEMINI_API_KEY',
    'ANTHROPIC_API_KEY',
    'TELEGRAM_BOT_TOKEN'
];
function snapshotEnvAndCwd() {
    const envBackup = {};
    for (const k of PROBE_KEYS)
        envBackup[k] = process.env[k];
    return { cwd: process.cwd(), envBackup };
}
function restoreEnvAndCwd(snap) {
    for (const k of PROBE_KEYS) {
        const v = snap.envBackup[k];
        if (v === undefined)
            delete process.env[k];
        else
            process.env[k] = v;
    }
    try {
        process.chdir(snap.cwd);
    }
    catch {
        /* best effort */
    }
}
function clearApiKeysAndProfile() {
    // Force the four oauth-downgrade checks to FAIL.
    delete process.env.OPENAI_API_KEY;
    delete process.env.GEMINI_API_KEY;
    delete process.env.ANTHROPIC_API_KEY;
    // Force cli:ollama check to actually run AND fail (PATH probably has no ollama).
    process.env.OPENLIFE_ENABLE_OLLAMA = 'true';
    // Default: clear the profile.
    delete process.env.OPENLIFE_RUNTIME_PROFILE;
}
function runDoctor() {
    // Late require — production code only loads on demand.
    const mod = require('../dist/cli/WorldClassCommands');
    const wc = new mod.WorldClassCommands();
    return wc.doctorWorldDetailed();
}
function findCheck(results, name) {
    return results.find((r) => r.name === name);
}
// -----------------------------------------------------------------------------
// Scenario A: default profile — failing oauth-downgrade names are NOT `info`.
//
// The default classifier in WorldClassCommands.ts routes:
//   - `cli:ollama`           → blocker (cli:* branch)
//   - `env:OPENAI_API_KEY`   → warning (no special branch, falls through)
//   - `env:GEMINI_API_KEY`   → warning
//   - `env:ANTHROPIC_API_KEY`→ warning
// The contract this test pins down is: none of them is `info` by default.
// (Scenario B verifies they ALL flip to `info` under oauth-only.)
// -----------------------------------------------------------------------------
function testDefaultProfileKeepsNonInfoSeverity() {
    const tmp = makeTempDir('default');
    const snap = snapshotEnvAndCwd();
    try {
        process.chdir(tmp);
        clearApiKeysAndProfile();
        // Explicitly NO profile set.
        assert(!process.env.OPENLIFE_RUNTIME_PROFILE, 'precondition: OPENLIFE_RUNTIME_PROFILE must be unset');
        const results = runDoctor();
        const expectedDefault = {
            'cli:ollama': 'blocker',
            'env:OPENAI_API_KEY': 'warning',
            'env:GEMINI_API_KEY': 'warning',
            'env:ANTHROPIC_API_KEY': 'warning'
        };
        for (const name of OAUTH_DOWNGRADE_NAMES) {
            const c = findCheck(results, name);
            assert(c, `default-profile: doctor result must include "${name}"`);
            // We forced these to fail (no API keys, no ollama on PATH typically).
            assert(c.ok === false, `default-profile: "${name}" must be failing for the test to be meaningful; got ok=${c.ok}`);
            assert(c.severity !== 'info', `default-profile: failing "${name}" must NOT be info without oauth-only profile; got "${c.severity}"`);
            assert(c.severity === expectedDefault[name], `default-profile: failing "${name}" must have severity="${expectedDefault[name]}" (default classifier); got "${c.severity}"`);
        }
    }
    finally {
        restoreEnvAndCwd(snap);
        fs.rmSync(tmp, { recursive: true, force: true });
    }
}
// -----------------------------------------------------------------------------
// Scenario B: oauth-only — failing oauth-downgrade names are `info`.
// -----------------------------------------------------------------------------
function testOauthOnlyDowngradesToInfo() {
    const tmp = makeTempDir('oauth');
    const snap = snapshotEnvAndCwd();
    try {
        process.chdir(tmp);
        clearApiKeysAndProfile();
        process.env.OPENLIFE_RUNTIME_PROFILE = 'oauth-only';
        const results = runDoctor();
        for (const name of OAUTH_DOWNGRADE_NAMES) {
            const c = findCheck(results, name);
            assert(c, `oauth-only: doctor result must include "${name}"`);
            assert(c.ok === false, `oauth-only: "${name}" must still be failing (no keys/ollama); got ok=${c.ok}`);
            assert(c.severity === 'info', `oauth-only: failing "${name}" must be downgraded to severity=info; got "${c.severity}"`);
        }
    }
    finally {
        restoreEnvAndCwd(snap);
        fs.rmSync(tmp, { recursive: true, force: true });
    }
}
// -----------------------------------------------------------------------------
// Scenario C: case-insensitive — `OAuth-Only` also downgrades.
// -----------------------------------------------------------------------------
function testOauthOnlyIsCaseInsensitive() {
    const tmp = makeTempDir('caseins');
    const snap = snapshotEnvAndCwd();
    try {
        process.chdir(tmp);
        clearApiKeysAndProfile();
        process.env.OPENLIFE_RUNTIME_PROFILE = 'OAuth-Only';
        const results = runDoctor();
        for (const name of OAUTH_DOWNGRADE_NAMES) {
            const c = findCheck(results, name);
            assert(c, `case-insensitive: doctor result must include "${name}"`);
            assert(c.ok === false, `case-insensitive: "${name}" must be failing`);
            assert(c.severity === 'info', `case-insensitive: "OAuth-Only" must downgrade "${name}" to severity=info; got "${c.severity}" — classifier .toLowerCase() contract broken?`);
        }
    }
    finally {
        restoreEnvAndCwd(snap);
        fs.rmSync(tmp, { recursive: true, force: true });
    }
}
// -----------------------------------------------------------------------------
// Scenario D: other failing checks are unaffected (not silently demoted).
// -----------------------------------------------------------------------------
function testOtherChecksUnaffectedByOauthOnly() {
    const tmp = makeTempDir('others');
    const snap = snapshotEnvAndCwd();
    try {
        process.chdir(tmp);
        clearApiKeysAndProfile();
        process.env.OPENLIFE_RUNTIME_PROFILE = 'oauth-only';
        // Telegram unset → env:TELEGRAM_BOT_TOKEN should fail and stay blocker.
        delete process.env.TELEGRAM_BOT_TOKEN;
        const results = runDoctor();
        // We expect at LEAST one failing non-downgraded check to be present so the
        // assertion has bite. cli:codex / cli:claude / env:TELEGRAM_BOT_TOKEN are
        // very likely to fail inside a fresh tmp dir with cleared env.
        const failingOthers = results.filter((r) => {
            if (r.ok)
                return false;
            if (OAUTH_DOWNGRADE_NAMES.includes(r.name))
                return false;
            // Only consider names the classifier flags as blocker/warning — i.e. names
            // that the classifier branches MAY have moved to blocker.
            const looksRouted = r.name.startsWith('runtime:') ||
                r.name.includes('TELEGRAM_BOT_TOKEN') ||
                r.name.startsWith('cli:') ||
                r.name.includes('promoted-assets') ||
                r.name.includes('security-events');
            return looksRouted;
        });
        assert(failingOthers.length > 0, 'precondition: at least one failing non-oauth-downgrade check must exist to make this scenario meaningful');
        for (const c of failingOthers) {
            assert(c.severity !== 'info', `oauth-only must NOT downgrade unrelated check "${c.name}" to info; got severity="${c.severity}"`);
        }
    }
    finally {
        restoreEnvAndCwd(snap);
        fs.rmSync(tmp, { recursive: true, force: true });
    }
}
async function main() {
    testDefaultProfileKeepsNonInfoSeverity();
    testOauthOnlyDowngradesToInfo();
    testOauthOnlyIsCaseInsensitive();
    testOtherChecksUnaffectedByOauthOnly();
    console.log('TEST_RUNTIME_PROFILE_OAUTH_ONLY_OK');
}
main().catch((err) => {
    console.error('TEST_RUNTIME_PROFILE_OAUTH_ONLY_FAIL:', err?.message || err);
    process.exit(1);
});
