import { RemoteRunnerRegistry } from './runner-registry.js';
import { deriveRemoteCapabilities } from './capabilities.js';
import { deriveRemoteHeartbeat } from './heartbeat.js';
import { deriveRemoteNegotiation } from './negotiation.js';
import { deriveRemoteRecoveryActions } from './recovery.js';
import { buildRemoteSessionStateSnapshot } from './session-state.js';
function stateIsDegraded(state) {
    return state === 'degraded' || state === 'reconnecting' || state === 'terminal_failure';
}
export class RemoteSupervisor {
    remoteRegistry;
    constructor(remoteRegistry) {
        this.remoteRegistry = remoteRegistry;
    }
    getSnapshot(store) {
        this.remoteRegistry.ensureContractsFromStore(store);
        const state = store.getState();
        const pools = this.remoteRegistry.listPools();
        const contracts = this.remoteRegistry.listContracts();
        const connections = [...state.acp.connections.values()];
        const runnerIds = new Set([
            ...connections.map((connection) => connection.agentId),
            ...contracts.map((contract) => contract.runnerId),
        ]);
        const sessions = [...runnerIds].map((runnerId) => this.describeRunner(runnerId, connections, contracts));
        return Object.freeze({
            capturedAt: Date.now(),
            totalConnections: connections.length,
            activeConnections: state.acp.activeConnectionIds.length,
            degradedConnections: sessions.filter((session) => stateIsDegraded(session.transportState) || session.heartbeat.status !== 'fresh').length,
            pools,
            sessions,
        });
    }
    describeRunner(runnerId, connections, contracts) {
        const connection = connections.find((entry) => entry.agentId === runnerId) ?? null;
        const contract = contracts.find((entry) => entry.runnerId === runnerId) ?? null;
        const capabilities = deriveRemoteCapabilities(contract, connection);
        const heartbeat = deriveRemoteHeartbeat(connection, contract);
        const negotiation = deriveRemoteNegotiation(contract, connection);
        const recovery = deriveRemoteRecoveryActions(connection, contract, heartbeat);
        return buildRemoteSessionStateSnapshot({
            runnerId,
            label: connection?.label ?? contract?.label ?? runnerId,
            connection,
            contract,
            heartbeat,
            negotiation,
            capabilities,
            recovery,
        });
    }
}
