"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeTunnelManagerClient = void 0;
const manager_server_1 = require("./manager-server");
const socket_1 = require("@applitools/socket");
const fs_1 = require("fs");
const net_1 = require("net");
async function makeTunnelManagerClient({ settings, logger, }) {
    const path = process.env.APPLITOOLS_TUNNEL_MANAGER_SOCK ||
        (process.platform === 'win32' ? '\\\\.\\pipe\\applitools-tunnel-manager' : '/tmp/applitools-tunnel-manager.sock');
    const socket = (0, socket_1.makeSocket)((0, net_1.createConnection)({ path }), { transport: 'ipc' });
    let server;
    socket.once('error', async (error) => {
        try {
            if (['ECONNREFUSED', 'ENOENT'].includes(error.code)) {
                if (error.code === 'ECONNREFUSED') {
                    try {
                        await fs_1.promises.unlink(path);
                    }
                    catch { }
                }
                logger.log(`Starting tunnel manager in separate process using path ${path} and settings`, settings);
                try {
                    server = await (0, manager_server_1.makeTunnelManagerServerProcess)({ settings, path });
                }
                catch (error) {
                    if (error.code !== 'EADDRINUSE')
                        throw error;
                }
            }
        }
        finally {
            socket.use((0, net_1.createConnection)({ path }));
        }
    });
    socket.once('ready', () => socket.target.unref());
    return {
        acquire: (options) => socket.request('Tunnel.acquire', options),
        release: (options) => socket.request('Tunnel.release', options),
        close: () => server === null || server === void 0 ? void 0 : server.close(),
    };
}
exports.makeTunnelManagerClient = makeTunnelManagerClient;
