"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.findAvailablePort = findAvailablePort;
const net_1 = __importDefault(require("net"));
const MAX_PORT = 65535;
/**
 * Returns true if something is already accepting TCP connections on the port.
 * Checks both IPv4 (127.0.0.1) and IPv6 (::1) since a server bound to ::1
 * won't block an IPv4 bind but will still serve traffic via 'localhost'.
 */
function isPortInUse(port) {
    function checkHost(host) {
        return new Promise((resolve) => {
            const socket = net_1.default.connect(port, host);
            socket.setTimeout(300);
            socket.on('connect', () => {
                socket.destroy();
                resolve(true);
            });
            socket.on('error', () => {
                socket.destroy();
                resolve(false);
            });
            socket.on('timeout', () => {
                socket.destroy();
                resolve(false);
            });
        });
    }
    return Promise.all([checkHost('127.0.0.1'), checkHost('::1')]).then(([v4, v6]) => v4 || v6);
}
/**
 * Finds an available TCP port starting from startPort.
 * A port is considered available only if:
 *   1. We can bind to it (no process owns it on 0.0.0.0 / ::)
 *   2. Nothing is already accepting connections on 127.0.0.1 or ::1
 *      (catches servers bound to ::1 that don't block an IPv4 bind)
 *
 * Throws if no free port is found before MAX_PORT (65535).
 */
async function findAvailablePort(startPort) {
    if (startPort > MAX_PORT) {
        throw new Error(`No available port found up to ${MAX_PORT}`);
    }
    const bindable = await new Promise((resolve) => {
        const server = net_1.default.createServer();
        server.listen(startPort, () => {
            server.close(() => resolve(true));
        });
        server.on('error', () => resolve(false));
    });
    if (!bindable || (await isPortInUse(startPort))) {
        return findAvailablePort(startPort + 1);
    }
    return startPort;
}
//# sourceMappingURL=portUtils.js.map