"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setTestExecutionProxyUrl = setTestExecutionProxyUrl;
exports.currentProxyConfig = currentProxyConfig;
exports.axiosProxyConfig = axiosProxyConfig;
exports.proxyUrlToPortConfig = proxyUrlToPortConfig;
const cliConfigProvider_1 = require("../providers/cliConfigProvider");
const hpagent_1 = require("hpagent");
const httpUtil_1 = require("./httpUtil");
const https_1 = require("https");
let testExecutionProxyUrl;
function setTestExecutionProxyUrl(url) {
    testExecutionProxyUrl = url;
}
async function currentProxyConfig(mode = 'mabl') {
    const httpConfig = (await cliConfigProvider_1.CliConfigProvider.getCliConfig()).http;
    return axiosProxyConfig(mode === 'test' ? httpConfig?.test : httpConfig?.mabl);
}
function axiosProxyConfig(httpConfig) {
    const config = {
        headers: {
            [httpUtil_1.USER_AGENT_HEADER]: httpUtil_1.USER_AGENT,
        },
    };
    let { proxyType, sslVerify } = httpConfig;
    if (testExecutionProxyUrl) {
        sslVerify = false;
        proxyType = 'current';
    }
    if (!sslVerify) {
        config.httpsAgent = new https_1.Agent({
            rejectUnauthorized: false,
        });
    }
    if (testExecutionProxyUrl || httpConfig.proxyHost?.href) {
        config.proxy = proxyUrlToPortConfig((testExecutionProxyUrl ?? httpConfig.proxyHost));
    }
    return maybeGetModifiedAxiosConfigForHttpProxy(config, sslVerify, proxyType);
}
function removeIpv6Brackets(input) {
    if (input.startsWith('[') && input.endsWith(']')) {
        return input.slice(1, -1);
    }
    return input;
}
function proxyUrlToPortConfig(proxyUrl) {
    const defaultPort = proxyUrl.protocol === 'https:' ? 443 : 80;
    const maybePortNumberMatch = proxyUrl.port;
    const portNumber = maybePortNumberMatch
        ? parseInt(maybePortNumberMatch)
        : defaultPort;
    const hostname = removeIpv6Brackets(proxyUrl.hostname);
    const config = {
        host: hostname,
        port: portNumber,
        protocol: proxyUrl.protocol,
    };
    if (proxyUrl.username || proxyUrl.password) {
        config.auth = {
            username: proxyUrl.username,
            password: proxyUrl.password,
        };
    }
    return config;
}
function maybeGetModifiedAxiosConfigForHttpProxy(config, sslVerify, _proxyType) {
    if (config.proxy &&
        (config.proxy?.protocol === 'http:' || config.proxy?.protocol === 'http')) {
        const newConfig = {
            ...config,
        };
        newConfig.proxy = false;
        const authConfig = config.proxy.auth;
        let proxyString = `${config.proxy?.protocol || 'http:'}//`;
        if (authConfig) {
            proxyString += `${authConfig.username}:${authConfig.password}@`;
        }
        if (config.proxy.host.includes(':')) {
            proxyString += `[${config.proxy.host}]`;
        }
        else {
            proxyString += config.proxy.host;
        }
        proxyString += `:${config.proxy.port}`;
        const parsedProxyUrl = new URL(proxyString);
        const hostname = removeIpv6Brackets(parsedProxyUrl.hostname);
        const proxyUrl = {
            hostname,
            port: parsedProxyUrl.port,
            protocol: parsedProxyUrl.protocol,
            username: parsedProxyUrl.username,
            password: parsedProxyUrl.password,
        };
        const rejectUnauthorized = sslVerify === true;
        const httpAgentConfig = {
            keepAlive: true,
            keepAliveMsecs: 1000,
            maxSockets: 256,
            maxFreeSockets: 256,
            proxy: proxyUrl,
            proxyRequestOptions: {
                rejectUnauthorized,
            },
        };
        const httpsAgentConfig = {
            ...httpAgentConfig,
            rejectUnauthorized,
        };
        console.log('Using proxy agent configuration', {
            ...httpsAgentConfig,
            proxy: {
                ...proxyUrl,
                username: proxyUrl.username ? '*****' : undefined,
                password: proxyUrl.password ? '*****' : undefined,
            },
        });
        newConfig.httpsAgent = new hpagent_1.HttpsProxyAgent(httpsAgentConfig);
        newConfig.httpAgent = new hpagent_1.HttpProxyAgent(httpAgentConfig);
        return newConfig;
    }
    return config;
}
