import { ProviderHealthManager } from './health-manager.js';
import { ProviderRegistry } from './provider-registry.js';
import { RouteLoadBalancer } from './load-balancer.js';
import { RoutingClassifier } from './classifier.js';
import { ContextAdvisor } from './context-advisor.js';
import { getStatsCenter } from '../../telemetry/stats-center.js';
import { loadRoutingInstructionStateSync, saveRoutingInstructionStateAsync, saveRoutingInstructionStateSync } from './sticky-session-store.js';
import { resolveStickyKey as resolveStickyKeyImpl, resolveSessionScope as resolveSessionScopeImpl } from './engine/routing-state/keys.js';
import { RouteAnalytics } from './engine/route-analytics.js';
import { StickySessionManager } from './engine/sticky-session-manager.js';
import { CooldownManager } from './engine/cooldown-manager.js';
import { routeRequest } from './engine-legacy/routing.js';
import { updateDeps as updateDepsImpl, initialize as initializeImpl } from './engine-legacy/config.js';
import { handleProviderError as handleProviderErrorImpl, handleProviderFailure as handleProviderFailureImpl, handleProviderSuccess as handleProviderSuccessImpl, buildHealthSnapshot as buildHealthSnapshotImpl, persistHealthSnapshot as persistHealthSnapshotImpl, markProviderCooldown as markProviderCooldownImpl, clearProviderCooldown as clearProviderCooldownImpl, isProviderCoolingDown as isProviderCoolingDownImpl, getProviderCooldownRemainingMs as getProviderCooldownRemainingMsImpl, restoreHealthFromStore as restoreHealthFromStoreImpl } from './engine-legacy/health.js';
import { getStopMessageState as getStopMessageStateImpl, getPreCommandState as getPreCommandStateImpl, getStatus as getStatusImpl } from './engine-legacy/state-accessors.js';
import { selectProvider as selectProviderImpl, selectFromCandidates as selectFromCandidatesImpl, selectFromStickyPool as selectFromStickyPoolImpl, extractExcludedProviderKeySet as extractExcludedProviderKeySetImpl } from './engine-legacy/selection-core.js';
import { parseDirectProviderModel as parseDirectProviderModelImpl, shouldFallbackDirectModelForMedia as shouldFallbackDirectModelForMediaImpl } from './engine-legacy/direct-model.js';
import { normalizeRouteAlias as normalizeRouteAliasImpl, buildRouteCandidates as buildRouteCandidatesImpl, reorderForInlineVision as reorderForInlineVisionImpl, reorderForPreferredModel as reorderForPreferredModelImpl, routeSupportsModel as routeSupportsModelImpl, routeSupportsInlineVision as routeSupportsInlineVisionImpl, sortByPriority as sortByPriorityImpl, routeWeight as routeWeightImpl, routeHasForceFlag as routeHasForceFlagImpl, routeHasTargets as routeHasTargetsImpl, hasPrimaryPool as hasPrimaryPoolImpl, sortRoutePools as sortRoutePoolsImpl, flattenPoolTargets as flattenPoolTargetsImpl } from './engine-legacy/route-utils.js';
import { resolveSelectionPenalty as resolveSelectionPenaltyImpl, resolveInstructionProcessModeForSelection as resolveInstructionProcessModeForSelectionImpl, resolveInstructionTarget as resolveInstructionTargetImpl, filterCandidatesByRoutingState as filterCandidatesByRoutingStateImpl, buildStickyRouteCandidatesFromFiltered as buildStickyRouteCandidatesFromFilteredImpl } from './engine-legacy/selection-state.js';
export class VirtualRouterEngine {
    routing = {};
    providerRegistry = new ProviderRegistry();
    healthManager = new ProviderHealthManager();
    loadBalancer = new RouteLoadBalancer();
    classifier = new RoutingClassifier({});
    contextAdvisor = new ContextAdvisor();
    contextRouting;
    routeAnalytics = new RouteAnalytics();
    stickySessionManager = new StickySessionManager();
    cooldownManager;
    antigravityLeasePersistence = { loadedOnce: false, loadedMtimeMs: null, flushTimer: null };
    debug = console; // thin hook; host may monkey-patch for colored logging
    healthConfig = null;
    statsCenter = getStatsCenter();
    // Derived flags from VirtualRouterConfig/routing used by process / response layers.
    webSearchForce = false;
    healthStore;
    routingStateStore = {
        loadSync: loadRoutingInstructionStateSync,
        saveAsync: saveRoutingInstructionStateAsync,
        saveSync: saveRoutingInstructionStateSync
    };
    routingInstructionState = new Map();
    quotaView;
    /**
     * Backward-compatible test/debug surface used by existing regression scripts.
     * Keep this as a read-only view over StickySessionManager storage.
     */
    get antigravitySessionAliasStore() {
        return this.stickySessionManager.getAllStores().sessionAliasStore;
    }
    constructor(deps) {
        this.cooldownManager = new CooldownManager({
            healthStore: deps?.healthStore,
            healthConfig: this.healthConfig,
            quotaView: deps?.quotaView
        });
        if (deps?.healthStore) {
            this.healthStore = deps.healthStore;
        }
        if (deps?.routingStateStore) {
            this.routingStateStore = deps.routingStateStore;
        }
        if (deps?.quotaView) {
            this.quotaView = deps.quotaView;
        }
    }
    updateDeps(deps) {
        updateDepsImpl(this, deps);
    }
    initialize(config) {
        initializeImpl(this, config);
    }
    route(request, metadata) {
        return routeRequest(this, request, metadata);
    }
    getStopMessageState(metadata) {
        return getStopMessageStateImpl(this, metadata);
    }
    getPreCommandState(metadata) {
        return getPreCommandStateImpl(this, metadata);
    }
    handleProviderFailure(event) {
        handleProviderFailureImpl(this, event);
    }
    handleProviderError(event) {
        handleProviderErrorImpl(this, event);
    }
    handleProviderSuccess(event) {
        handleProviderSuccessImpl(this, event);
    }
    getStatus() {
        return getStatusImpl(this);
    }
    normalizeRouteAlias(routeName) {
        return normalizeRouteAliasImpl(routeName);
    }
    buildRouteCandidates(requestedRoute, classificationCandidates, features) {
        return buildRouteCandidatesImpl(this, requestedRoute, classificationCandidates, features);
    }
    reorderForInlineVision(routeNames) {
        return reorderForInlineVisionImpl(this, routeNames);
    }
    reorderForPreferredModel(routeNames, modelId) {
        return reorderForPreferredModelImpl(this, routeNames, modelId);
    }
    routeSupportsModel(routeName, modelId) {
        return routeSupportsModelImpl(this, routeName, modelId);
    }
    routeSupportsInlineVision(routeName) {
        return routeSupportsInlineVisionImpl(this, routeName);
    }
    sortByPriority(routeNames) {
        return sortByPriorityImpl(routeNames);
    }
    routeWeight(routeName) {
        return routeWeightImpl(routeName);
    }
    routeHasForceFlag(routeName) {
        return routeHasForceFlagImpl(this, routeName);
    }
    routeHasTargets(pools) {
        return routeHasTargetsImpl(this, pools);
    }
    hasPrimaryPool(pools) {
        return hasPrimaryPoolImpl(this, pools);
    }
    sortRoutePools(pools) {
        return sortRoutePoolsImpl(this, pools);
    }
    flattenPoolTargets(pools) {
        return flattenPoolTargetsImpl(this, pools);
    }
    markProviderCooldown(providerKey, cooldownMs) {
        markProviderCooldownImpl(this, providerKey, cooldownMs);
    }
    clearProviderCooldown(providerKey) {
        clearProviderCooldownImpl(this, providerKey);
    }
    isProviderCoolingDown(providerKey) {
        return isProviderCoolingDownImpl(this, providerKey);
    }
    getProviderCooldownRemainingMs(providerKey) {
        return getProviderCooldownRemainingMsImpl(this, providerKey);
    }
    restoreHealthFromStore() {
        restoreHealthFromStoreImpl(this);
    }
    buildHealthSnapshot() {
        return buildHealthSnapshotImpl(this);
    }
    persistHealthSnapshot() {
        persistHealthSnapshotImpl(this);
    }
    parseDirectProviderModel(model) {
        return parseDirectProviderModelImpl(this, model);
    }
    shouldFallbackDirectModelForMedia(direct, features) {
        return shouldFallbackDirectModelForMediaImpl(this, direct, features);
    }
    selectProvider(requestedRoute, metadata, classification, features, routingState) {
        return selectProviderImpl(this, requestedRoute, metadata, classification, features, routingState);
    }
    selectFromCandidates(routes, metadata, classification, features, state, requiredProviderKeys, allowAliasRotation) {
        return selectFromCandidatesImpl(this, routes, metadata, classification, features, state, requiredProviderKeys, allowAliasRotation);
    }
    selectFromStickyPool(stickyKeySet, metadata, features, state, allowAliasRotation) {
        return selectFromStickyPoolImpl(this, stickyKeySet, metadata, features, state, allowAliasRotation);
    }
    extractExcludedProviderKeySet(metadata) {
        return extractExcludedProviderKeySetImpl(this, metadata);
    }
    resolveSelectionPenalty(providerKey) {
        return resolveSelectionPenaltyImpl(this, providerKey);
    }
    resolveInstructionProcessModeForSelection(providerKey, routingState) {
        return resolveInstructionProcessModeForSelectionImpl(this, providerKey, routingState);
    }
    resolveInstructionTarget(target) {
        return resolveInstructionTargetImpl(this, target);
    }
    buildStickyRouteCandidatesFromFiltered(filteredCandidates, stickyKeySet) {
        return buildStickyRouteCandidatesFromFilteredImpl(this, filteredCandidates, stickyKeySet);
    }
    filterCandidatesByRoutingState(routes, state) {
        return filterCandidatesByRoutingStateImpl(this, routes, state);
    }
    resolveStickyKey(metadata) {
        return resolveStickyKeyImpl(metadata);
    }
    resolveSessionScope(metadata) {
        return resolveSessionScopeImpl(metadata);
    }
}
