"use strict";
// src/test_host_invoker.ts
// v1.17.0 — HostInvoker + adapter registry regression.
//
// Uses MockAdapter exclusively to avoid spawning real CLIs. Asserts:
//   1. Default registry has all 4 adapters
//   2. OPENLIFE_HOST_ADAPTER env routes to the right one
//   3. MockAdapter cycles through canned responses
//   4. Unavailable adapter returns adapter_unavailable error
//   5. Unknown adapter name returns adapter_not_registered error
Object.defineProperty(exports, "__esModule", { value: true });
const HostInvoker_1 = require("./orchestrator/story/HostInvoker");
const MockAdapter_1 = require("./orchestrator/story/adapters/MockAdapter");
function assert(cond, msg) {
    if (!cond)
        throw new Error(`assertion failed: ${msg}`);
}
function setEnv(key, value) {
    const prev = process.env[key];
    if (value === undefined)
        delete process.env[key];
    else
        process.env[key] = value;
    return () => { if (prev === undefined)
        delete process.env[key];
    else
        process.env[key] = prev; };
}
function scenarioDefaultRegistry() {
    HostInvoker_1.HostInvoker._resetForTests();
    const registered = HostInvoker_1.HostInvoker._listRegistered();
    for (const name of ['claude', 'gemini', 'codex', 'mock']) {
        assert(registered.includes(name), `${name} should be registered, got ${registered.join(',')}`);
    }
    console.log('✅ scenario 1: default registry has claude, gemini, codex, mock');
}
async function scenarioMockCycles() {
    HostInvoker_1.HostInvoker._resetForTests();
    MockAdapter_1.MockAdapter._reset();
    const restore = setEnv('OPENLIFE_MOCK_ADAPTER_SCRIPT', JSON.stringify({
        responses: ['first', 'second', 'third'],
    }));
    try {
        const r1 = await HostInvoker_1.HostInvoker.invoke('q', { provider: 'mock' });
        const r2 = await HostInvoker_1.HostInvoker.invoke('q', { provider: 'mock' });
        const r3 = await HostInvoker_1.HostInvoker.invoke('q', { provider: 'mock' });
        const r4 = await HostInvoker_1.HostInvoker.invoke('q', { provider: 'mock' });
        assert(r1.ok && r1.text === 'first', `r1 expected 'first', got '${r1.text}'`);
        assert(r2.text === 'second', `r2: got '${r2.text}'`);
        assert(r3.text === 'third', `r3`);
        assert(r4.text === 'first', `cycle wraps: got '${r4.text}'`);
        assert(r1.adapter === 'mock', 'adapter reported');
    }
    finally {
        restore();
        MockAdapter_1.MockAdapter._reset();
    }
    console.log('✅ scenario 2: MockAdapter cycles through canned responses');
}
async function scenarioEnvRoute() {
    HostInvoker_1.HostInvoker._resetForTests();
    MockAdapter_1.MockAdapter._reset();
    const restoreEnv = setEnv('OPENLIFE_HOST_ADAPTER', 'mock');
    const restoreScript = setEnv('OPENLIFE_MOCK_ADAPTER_SCRIPT', 'env-routed-response');
    try {
        // No explicit provider — should route via env to mock.
        const r = await HostInvoker_1.HostInvoker.invoke('q');
        assert(r.ok && r.adapter === 'mock', `expected mock via env, got ${r.adapter}`);
        assert(r.text === 'env-routed-response', `text: ${r.text}`);
    }
    finally {
        restoreEnv();
        restoreScript();
        MockAdapter_1.MockAdapter._reset();
    }
    console.log('✅ scenario 3: OPENLIFE_HOST_ADAPTER env routes correctly');
}
async function scenarioUnknownAdapter() {
    HostInvoker_1.HostInvoker._resetForTests();
    const r = await HostInvoker_1.HostInvoker.invoke('q', { provider: 'nonexistent' });
    assert(!r.ok, 'unknown adapter fails');
    assert(r.error?.includes('adapter_not_registered'), `expected adapter_not_registered, got ${r.error}`);
    console.log('✅ scenario 4: unknown adapter → adapter_not_registered');
}
async function scenarioUnavailableAdapter() {
    HostInvoker_1.HostInvoker._resetForTests();
    // Inject a synthetic adapter that reports unavailable.
    const fakeUnavailable = {
        name: 'mock', // mock to override the default
        async isAvailable() { return false; },
        async invoke(_p, _o) {
            return { ok: true, text: 'should not run', exitCode: 0, durationMs: 0, adapter: 'mock' };
        },
    };
    HostInvoker_1.HostInvoker.register(fakeUnavailable);
    const r = await HostInvoker_1.HostInvoker.invoke('q', { provider: 'mock' });
    assert(!r.ok, 'unavailable adapter fails');
    assert(r.error?.includes('adapter_unavailable'), `expected adapter_unavailable, got ${r.error}`);
    HostInvoker_1.HostInvoker._resetForTests();
    MockAdapter_1.MockAdapter._reset();
    console.log('✅ scenario 5: unavailable adapter → adapter_unavailable');
}
(async () => {
    try {
        scenarioDefaultRegistry();
        await scenarioMockCycles();
        await scenarioEnvRoute();
        await scenarioUnknownAdapter();
        await scenarioUnavailableAdapter();
        console.log('TEST_HOST_INVOKER_OK');
    }
    catch (err) {
        console.error('TEST_HOST_INVOKER_FAIL', err);
        process.exit(1);
    }
})();
