import { loadConfig, loadSelectors } from './config.js';
import { CDPBridge } from './cdp-bridge.js';
import { DOMExtractor } from './dom-extractor.js';
import { CommandExecutor } from './command-executor.js';
import { StateManager } from './state-manager.js';
import { JsonlIndex } from './jsonl-index.js';
import { WindowMonitor } from './window-monitor.js';
import { Relay } from './relay.js';
import { MessageDebugStore } from './message-debug-store.js';
import { connectorClientVersion } from './connector-client-version.js';
import { installEditorListSync } from './editor-list-sync.js';
import { QueuedMediaHints } from './queued-media-hints.js';
import { installKeepAwakeShutdown, startKeepAwake } from './keep-awake.js';
async function main() {
    const config = loadConfig();
    startKeepAwake(config.keepAwakeEnabled);
    installKeepAwakeShutdown();
    const selectors = loadSelectors();
    const connectorVersion = connectorClientVersion();
    console.log('=== Cursor Connect Bridge ===');
    console.log(`Connector version: ${connectorVersion} (env=${process.env.CURSORCONNECT_CLI_VERSION?.trim() || '-'})`);
    console.log(`CDP: ${config.cdpUrl}`);
    console.log(`Server: http://${config.serverHost}:${config.serverPort}`);
    if (config.relayUrl) {
        console.log(`Relay upstream: ${config.relayUrl} (room=${config.relayRoomId})`);
        if (config.relayKeepaliveMs > 0) {
            console.log(`Relay keepalive: every ${config.relayKeepaliveMs}ms`);
        }
    }
    if (config.keepAwakeEnabled) {
        console.log('Keep-awake: on (macOS caffeinate)');
    }
    console.log(`Projects: ${config.cursorProjectsDir}`);
    const stateManager = new StateManager(config.debounceMs);
    installEditorListSync(stateManager);
    const queuedMediaHints = new QueuedMediaHints();
    const commandExecutor = new CommandExecutor(selectors, queuedMediaHints);
    const cdpBridge = new CDPBridge(config);
    const jsonlIndex = new JsonlIndex(config.cursorProjectsDir);
    jsonlIndex.setBridgeStateProvider(() => stateManager.getState());
    const messageDebugStore = new MessageDebugStore();
    const extractor = new DOMExtractor(selectors, (state, err) => {
        if (state?.messageDebug)
            messageDebugStore.push(state.messageDebug);
        if (state)
            stateManager.onExtraction(state);
        else
            stateManager.onExtraction(null, err);
    }, queuedMediaHints);
    const windowMonitor = new WindowMonitor(cdpBridge, stateManager, selectors, config);
    cdpBridge.on('connected', () => {
        stateManager.onConnectionChanged(true);
        stateManager.updateWindows(cdpBridge.windows, cdpBridge.activeTargetId);
        commandExecutor.setClient(cdpBridge.getClient());
        const client = cdpBridge.getClient();
        if (client)
            extractor.start(client, config.pollIntervalMs);
        windowMonitor.start();
    });
    cdpBridge.on('disconnected', () => {
        stateManager.onConnectionChanged(false);
        commandExecutor.setClient(null);
        extractor.stop();
        windowMonitor.stop();
    });
    const relay = new Relay(config, stateManager, commandExecutor, cdpBridge, jsonlIndex, messageDebugStore, extractor);
    await relay.listen();
    jsonlIndex.start();
    await cdpBridge.start();
    stateManager.updateWindows(cdpBridge.windows, cdpBridge.activeTargetId);
    const syncWindows = async () => {
        await cdpBridge.refreshWindows();
        const switched = config.focusSyncEnabled && !cdpBridge.isFocusSyncSuppressed()
            ? await cdpBridge.syncToForegroundWindow()
            : false;
        stateManager.updateWindows(cdpBridge.windows, cdpBridge.activeTargetId);
        if (switched)
            extractor.pollNow();
    };
    setInterval(() => void syncWindows(), config.focusSyncIntervalMs);
}
main().catch((err) => {
    console.error('[main] fatal:', err);
    process.exit(1);
});
