"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Ports = void 0;
const node_net_1 = __importDefault(require("node:net"));
const constants_1 = require("../../constants");
const IocdWdioServiceError_1 = require("../../utils/error/IocdWdioServiceError");
const Logger_1 = require("./Logger");
/**
 * Helpers for working with TCP ports.
 *
 * - `findFreePort`: binds to port 0 and resolves with an available port.
 * - `waitForPort`: polls a host/port until it accepts connections.
 *
 * Used to allocate and verify ports for ChromeDriver, DevTools,
 * and the platform runtime.
 */
class Ports {
    static findFreePort() {
        return new Promise((resolve, reject) => {
            const server = node_net_1.default.createServer();
            server.listen(0, () => {
                const address = server.address();
                if (typeof address === 'object' && address?.port) {
                    const port = address.port;
                    server.close(() => resolve(port));
                }
                else {
                    reject(new IocdWdioServiceError_1.IocdWdioServiceError('Unable to find free port.'));
                }
            });
            server.on('error', reject);
        });
    }
    static waitForPort(port, host = constants_1.LOCALHOST) {
        this.logger.info('Waiting for port', port);
        return new Promise(resolve => {
            const tryConnect = () => {
                const socket = node_net_1.default.createConnection(port, host);
                socket.once('connect', () => {
                    this.logger.info('Port is ready', port);
                    socket.end();
                    resolve();
                });
                socket.once('error', () => {
                    setTimeout(tryConnect, 250);
                });
            };
            tryConnect();
        });
    }
}
exports.Ports = Ports;
Ports.logger = (0, Logger_1.Logger)('Ports');
