/**
 * Antigravity 자동 발견 모듈
 * 
 * localhost의 CDP 포트 범위를 스캔하여 실행 중인 Antigravity 인스턴스를 감지.
 * 발견된 인스턴스는 자동으로 세션 생성하여 웹 UI에 표시.
 */

const http = require('http');

// 스캔할 포트 범위
const SCAN_PORTS = [9000, 9222, 9229, 9333, 9001, 9002, 9003, 9004, 9005];
const SCAN_INTERVAL_MS = 15000; // 15초마다 스캔

/**
 * 특정 포트의 CDP 엔드포인트에 요청하여 Antigravity인지 확인
 * @returns {Promise<{port, title, url}|null>}
 */
function probeCDPPort(host, port, timeoutMs = 2000) {
    return new Promise((resolve) => {
        const req = http.get(`http://${host}:${port}/json`, { timeout: timeoutMs }, (res) => {
            let data = '';
            res.on('data', chunk => data += chunk);
            res.on('end', () => {
                try {
                    const targets = JSON.parse(data);
                    // Antigravity 워크벤치 타겟 찾기
                    const mainTarget = targets.find(t =>
                        t.type === 'page' &&
                        t.url.includes('workbench.html') &&
                        !t.url.includes('jetski')
                    );
                    if (mainTarget) {
                        resolve({
                            port,
                            title: mainTarget.title || 'Antigravity',
                            url: mainTarget.url,
                        });
                    } else {
                        resolve(null);
                    }
                } catch {
                    resolve(null);
                }
            });
        });
        req.on('error', () => resolve(null));
        req.on('timeout', () => { req.destroy(); resolve(null); });
    });
}

/**
 * 모든 포트를 병렬 스캔하여 Antigravity 인스턴스 목록 반환
 * @returns {Promise<Array<{port, title, url}>>}
 */
async function scanForAntigravity(host = 'localhost') {
    const probes = SCAN_PORTS.map(port => probeCDPPort(host, port));
    const results = await Promise.all(probes);
    return results.filter(Boolean);
}

class AutoDiscovery {
    constructor(options = {}) {
        this.host = options.host || 'localhost';
        this.intervalMs = options.intervalMs || SCAN_INTERVAL_MS;
        this.onDiscovered = options.onDiscovered || null; // callback({port, title, url})
        this.onLost = options.onLost || null; // callback(port)
        this.knownPorts = new Set();
        this.timer = null;
    }

    /**
     * 자동 발견 시작
     */
    async start() {
        console.log(`[AutoDiscovery] 시작 — ${this.host}에서 Antigravity 포트 스캔`);

        // 즉시 한 번 스캔
        await this._scan();

        // 주기적 스캔
        this.timer = setInterval(() => this._scan(), this.intervalMs);
    }

    /**
     * 자동 발견 중지
     */
    stop() {
        if (this.timer) {
            clearInterval(this.timer);
            this.timer = null;
        }
    }

    /**
     * 내부 스캔 로직
     */
    async _scan() {
        try {
            const found = await scanForAntigravity(this.host);
            const foundPorts = new Set(found.map(f => f.port));

            // 새로 발견된 인스턴스
            for (const instance of found) {
                if (!this.knownPorts.has(instance.port)) {
                    this.knownPorts.add(instance.port);
                    console.log(`[AutoDiscovery] 발견: ${this.host}:${instance.port} — ${instance.title}`);
                    if (this.onDiscovered) {
                        this.onDiscovered(instance);
                    }
                }
            }

            // 사라진 인스턴스
            for (const port of this.knownPorts) {
                if (!foundPorts.has(port)) {
                    this.knownPorts.delete(port);
                    console.log(`[AutoDiscovery] 소실: ${this.host}:${port}`);
                    if (this.onLost) {
                        this.onLost(port);
                    }
                }
            }
        } catch (err) {
            console.error('[AutoDiscovery] 스캔 오류:', err.message);
        }
    }
}

module.exports = { AutoDiscovery, scanForAntigravity, probeCDPPort };
