/**
 * @license
 * Copyright 2025 Vybestack LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { AsyncLocalStorage } from 'node:async_hooks';
import * as os from 'node:os';
import * as path from 'node:path';
import { Config, MultiProviderTokenStore, ProviderManager, SettingsService, clearActiveProviderRuntimeContext, createProviderRuntimeContext, flushRuntimeAuthScope, ProfileManager, SubagentManager, } from '@vybestack/llxprt-code-core';
import { OAuthManager } from '../auth/oauth-manager.js';
const DEFAULT_MODEL = 'gemini-1.5-flash';
const DEFAULT_DEBUG_MODE = false;
let sharedTokenStore = null;
let activationBindings = null;
let runtimeCounter = 0;
const runtimeScope = new AsyncLocalStorage();
export function enterRuntimeScope(scope) {
    runtimeScope.enterWith(scope);
}
export function runWithRuntimeScope(scope, callback) {
    return runtimeScope.run(scope, callback);
}
export function getCurrentRuntimeScope() {
    return runtimeScope.getStore();
}
/**
 * @plan:PLAN-20251018-STATELESSPROVIDER2.P03
 * @requirement:REQ-SP2-002
 * @pseudocode multi-runtime-baseline.md lines 6-6
 * Cache CLI activation bindings (reset/context/infrastructure/link) for deterministic invocation.
 */
export function registerIsolatedRuntimeBindings(bindings) {
    activationBindings = bindings;
}
/**
 * @plan:PLAN-20251018-STATELESSPROVIDER2.P03
 * @requirement:REQ-SP2-002
 * @pseudocode multi-runtime-baseline.md lines 2-5
 * Construct an isolated runtime using shared immutable resources and scoped services.
 */
export function createIsolatedRuntimeContext(options = {}) {
    if (!activationBindings) {
        throw new Error('Isolated runtime activation bindings must be registered before creating contexts.');
    }
    const runtimeId = options.runtimeId ??
        `cli-isolated-${Date.now().toString(16)}-${(runtimeCounter += 1).toString(16)}`;
    const workspaceDir = options.workspaceDir ?? process.cwd();
    const baseMetadata = {
        source: 'cli-isolated-runtime-factory',
        ...(options.metadata ?? {}),
    };
    const settingsService = options.config?.getSettingsService() ??
        options.settingsService ??
        new SettingsService();
    const model = options.model ?? DEFAULT_MODEL;
    const debugMode = options.debugMode ?? DEFAULT_DEBUG_MODE;
    const config = options.config ??
        new Config({
            sessionId: runtimeId,
            targetDir: workspaceDir,
            debugMode,
            cwd: workspaceDir,
            model,
            settingsService,
        });
    const configWithManagers = config;
    const optionsConfigWithManagers = options.config;
    const llxprtDir = path.join(os.homedir(), '.llxprt');
    const resolvedProfileManager = optionsConfigWithManagers?.getProfileManager?.() ??
        configWithManagers.getProfileManager?.() ??
        new ProfileManager(path.join(llxprtDir, 'profiles'));
    const resolvedSubagentManager = optionsConfigWithManagers?.getSubagentManager?.() ??
        configWithManagers.getSubagentManager?.() ??
        new SubagentManager(path.join(llxprtDir, 'subagents'), resolvedProfileManager);
    configWithManagers.setProfileManager?.(resolvedProfileManager);
    configWithManagers.setSubagentManager?.(resolvedSubagentManager);
    const resolvedSettingsService = config.getSettingsService() ?? settingsService;
    const tokenStore = sharedTokenStore ?? (sharedTokenStore = new MultiProviderTokenStore()); // Step 1 (multi-runtime-baseline.md line 2) keeps token storage shared.
    const oauthManager = options.oauthManager ?? new OAuthManager(tokenStore);
    const initialRuntimeContext = createProviderRuntimeContext({
        settingsService: resolvedSettingsService,
        config,
        runtimeId,
        metadata: baseMetadata,
    });
    const providerManager = new ProviderManager({
        runtime: initialRuntimeContext,
        settingsService: resolvedSettingsService,
        config,
    });
    let currentRuntimeId = runtimeId;
    let currentMetadata = baseMetadata;
    let active = false;
    /**
     * @plan:PLAN-20251018-STATELESSPROVIDER2.P03
     * @requirement:REQ-SP2-002
     * @pseudocode multi-runtime-baseline.md lines 7-7
     * Execute the activation flow in the reset → context → infrastructure → link order per Step 6.
     */
    const activate = async (activationOptions) => {
        if (!activationBindings) {
            throw new Error('Isolated runtime activation bindings must be registered before activation.');
        }
        const bindings = activationBindings;
        currentRuntimeId = activationOptions?.runtimeId ?? runtimeId;
        currentMetadata = {
            ...baseMetadata,
            ...(activationOptions?.metadata ?? {}),
        };
        const scope = {
            runtimeId: currentRuntimeId,
            metadata: currentMetadata,
        };
        enterRuntimeScope(scope);
        await runWithRuntimeScope(scope, async () => {
            const scopedRuntime = createProviderRuntimeContext({
                settingsService: resolvedSettingsService,
                config,
                runtimeId: currentRuntimeId,
                metadata: currentMetadata,
            });
            providerManager.runtime = scopedRuntime;
            await Promise.resolve(bindings.resetInfrastructure());
            await Promise.resolve(bindings.setRuntimeContext(resolvedSettingsService, config, {
                runtimeId: currentRuntimeId,
                metadata: currentMetadata,
            }));
            if (options.prepare) {
                await options.prepare({
                    config,
                    settingsService: resolvedSettingsService,
                    providerManager,
                    oauthManager,
                    runtimeId: currentRuntimeId,
                    metadata: currentMetadata,
                });
            }
            await Promise.resolve(bindings.registerInfrastructure(providerManager, oauthManager));
            await Promise.resolve(bindings.linkProviderManager(config, providerManager));
            active = true;
        });
    };
    /**
     * @plan:PLAN-20251018-STATELESSPROVIDER2.P03
     * @requirement:REQ-SP2-002
     * @pseudocode multi-runtime-baseline.md lines 8-8
     * Clear activation state and invoke onCleanup hooks in the reverse order detailed in Step 7.
     */
    const cleanup = async () => {
        if (!active && !options.onCleanup) {
            return;
        }
        const scope = {
            runtimeId: currentRuntimeId,
            metadata: currentMetadata,
        };
        const bindings = activationBindings;
        await runWithRuntimeScope(scope, async () => {
            if (bindings) {
                await Promise.resolve(bindings.resetInfrastructure());
            }
            clearActiveProviderRuntimeContext();
            const revocation = flushRuntimeAuthScope(currentRuntimeId);
            if (options.onCleanup) {
                await options.onCleanup({
                    config,
                    settingsService: resolvedSettingsService,
                    providerManager,
                    runtimeId: currentRuntimeId,
                    metadata: currentMetadata,
                });
            }
            if (bindings?.disposeRuntime) {
                await Promise.resolve(bindings.disposeRuntime(currentRuntimeId, revocation));
            }
        });
        active = false;
    };
    return {
        runtimeId,
        metadata: baseMetadata,
        settingsService: resolvedSettingsService,
        config,
        providerManager,
        oauthManager,
        activate,
        cleanup,
    };
}
//# sourceMappingURL=runtimeContextFactory.js.map