"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.shouldBypassProxy = exports.getNoProxyValue = exports.isLoopbackHost = exports.getProxyUrl = exports.getProxyResolution = void 0;
function getEnvValue(env, keys) {
    for (const key of keys) {
        const value = env[key];
        if (typeof value === 'string') {
            const trimmed = value.trim();
            if (trimmed.length > 0) {
                return trimmed;
            }
        }
    }
    return undefined;
}
function normalizeHostname(hostname) {
    const trimmed = hostname.trim().toLowerCase().replace(/\.$/, '');
    if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
        return trimmed.slice(1, -1);
    }
    return trimmed;
}
function isIpLikeHost(hostname) {
    return /^[\d.:]+$/.test(hostname);
}
function validateProxyUrl(proxyUrl, allowedProtocols) {
    let parsedUrl;
    try {
        parsedUrl = new URL(proxyUrl);
    }
    catch {
        throw new Error('Invalid URL');
    }
    if (allowedProtocols && !allowedProtocols.includes(parsedUrl.protocol)) {
        throw new Error(`Unsupported proxy protocol: ${parsedUrl.protocol}`);
    }
    return proxyUrl;
}
function getProxyKeys(isHttps) {
    if (isHttps) {
        return ['https_proxy', 'HTTPS_PROXY', 'http_proxy', 'HTTP_PROXY', 'all_proxy', 'ALL_PROXY'];
    }
    return ['http_proxy', 'HTTP_PROXY', 'all_proxy', 'ALL_PROXY'];
}
function getProxyResolution(isHttps, env = process.env, options = {}) {
    let firstError;
    for (const key of getProxyKeys(isHttps)) {
        const proxyUrl = getEnvValue(env, [key]);
        if (!proxyUrl) {
            continue;
        }
        try {
            return { url: validateProxyUrl(proxyUrl, options.allowedProtocols) };
        }
        catch (error) {
            if (!firstError) {
                firstError = error instanceof Error ? error.message : 'Unknown proxy configuration error';
            }
        }
    }
    return { error: firstError };
}
exports.getProxyResolution = getProxyResolution;
function getProxyUrl(isHttps, env = process.env) {
    const { url } = getProxyResolution(isHttps, env);
    return url;
}
exports.getProxyUrl = getProxyUrl;
function isLoopbackHost(hostname) {
    const normalizedHost = normalizeHostname(hostname);
    if (!normalizedHost) {
        return false;
    }
    if (normalizedHost === 'localhost' ||
        normalizedHost.endsWith('.localhost') ||
        normalizedHost === '0.0.0.0' ||
        normalizedHost === '::1') {
        return true;
    }
    if (/^127(?:\.\d{1,3}){3}$/.test(normalizedHost)) {
        return true;
    }
    return normalizedHost.startsWith('::ffff:127.') || normalizedHost.startsWith('::ffff:7f');
}
exports.isLoopbackHost = isLoopbackHost;
function getNoProxyValue(env = process.env) {
    return getEnvValue(env, ['no_proxy', 'NO_PROXY']);
}
exports.getNoProxyValue = getNoProxyValue;
function shouldBypassProxy(hostname, env = process.env) {
    const normalizedHost = normalizeHostname(hostname);
    if (!normalizedHost) {
        return false;
    }
    if (isLoopbackHost(normalizedHost)) {
        return true;
    }
    const noProxy = getNoProxyValue(env);
    if (!noProxy) {
        return false;
    }
    const patterns = noProxy
        .split(/[,\s]+/)
        .map((pattern) => normalizeHostname(pattern))
        .filter(Boolean);
    for (const pattern of patterns) {
        if (pattern === '*') {
            return true;
        }
        const canonicalPattern = pattern.startsWith('.')
            ? pattern.slice(1)
            : pattern.replace(/^\*\.?/, '');
        if (!canonicalPattern) {
            continue;
        }
        if (normalizedHost === canonicalPattern) {
            return true;
        }
        if (!isIpLikeHost(canonicalPattern) && normalizedHost.endsWith(`.${canonicalPattern}`)) {
            return true;
        }
    }
    return false;
}
exports.shouldBypassProxy = shouldBypassProxy;
//# sourceMappingURL=proxy-env.js.map