"use strict";
/**
 * Global Fetch Proxy Setup
 *
 * Configures undici's global dispatcher to respect standard proxy environment
 * variables without routing CCS loopback traffic back through the proxy.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyGlobalFetchProxy = exports.createGlobalFetchProxyDispatcher = void 0;
const undici_1 = require("undici");
const proxy_env_1 = require("./proxy-env");
const FETCH_PROXY_PROTOCOLS = ['http:', 'https:'];
class RoutingProxyDispatcher extends undici_1.Dispatcher {
    constructor(httpProxyUrl, httpsProxyUrl) {
        super();
        this.directDispatcher = new undici_1.Agent();
        this.httpProxyDispatcher = httpProxyUrl ? new undici_1.ProxyAgent(httpProxyUrl) : null;
        this.httpsProxyDispatcher = httpsProxyUrl ? new undici_1.ProxyAgent(httpsProxyUrl) : null;
    }
    dispatch(options, handler) {
        return this.resolveDispatcher(options.origin).dispatch(options, handler);
    }
    close(callback) {
        const promise = Promise.all(this.getDispatchers().map((dispatcher) => dispatcher.close())).then(() => undefined);
        if (callback) {
            promise.then(() => callback(), () => callback());
            return;
        }
        return promise;
    }
    destroy(errOrCallback, callback) {
        const error = typeof errOrCallback === 'function' ? null : errOrCallback;
        const done = typeof errOrCallback === 'function' ? errOrCallback : callback;
        const promise = Promise.all(this.getDispatchers().map((dispatcher) => dispatcher.destroy(error ?? null))).then(() => undefined);
        if (done) {
            promise.then(() => done(), () => done());
            return;
        }
        return promise;
    }
    resolveDispatcher(origin) {
        if (!origin) {
            return this.directDispatcher;
        }
        let url;
        try {
            url = origin instanceof URL ? origin : new URL(origin);
        }
        catch {
            return this.directDispatcher;
        }
        if ((0, proxy_env_1.shouldBypassProxy)(url.hostname)) {
            return this.directDispatcher;
        }
        if (url.protocol === 'https:' && this.httpsProxyDispatcher) {
            return this.httpsProxyDispatcher;
        }
        if (url.protocol === 'http:' && this.httpProxyDispatcher) {
            return this.httpProxyDispatcher;
        }
        return this.directDispatcher;
    }
    getDispatchers() {
        return Array.from(new Set([this.directDispatcher, this.httpProxyDispatcher, this.httpsProxyDispatcher].filter((dispatcher) => dispatcher !== null)));
    }
}
function createGlobalFetchProxyDispatcher() {
    const { httpProxyUrl, httpsProxyUrl } = resolveGlobalFetchProxyConfig();
    if (!httpProxyUrl && !httpsProxyUrl) {
        return null;
    }
    return new RoutingProxyDispatcher(httpProxyUrl, httpsProxyUrl);
}
exports.createGlobalFetchProxyDispatcher = createGlobalFetchProxyDispatcher;
function applyGlobalFetchProxy() {
    try {
        const config = resolveGlobalFetchProxyConfig();
        if (!config.httpProxyUrl && !config.httpsProxyUrl) {
            return config.error ? { enabled: false, error: config.error } : { enabled: false };
        }
        const dispatcher = createGlobalFetchProxyDispatcher();
        if (!dispatcher) {
            return { enabled: false };
        }
        (0, undici_1.setGlobalDispatcher)(dispatcher);
        globalThis.fetch = undici_1.fetch;
        return { enabled: true };
    }
    catch (error) {
        const message = error instanceof Error ? error.message : 'Unknown proxy configuration error';
        return { enabled: false, error: message };
    }
}
exports.applyGlobalFetchProxy = applyGlobalFetchProxy;
const setupResult = applyGlobalFetchProxy();
if (setupResult.error) {
    console.error(`[!] Skipping global fetch proxy setup: ${setupResult.error}`);
}
function resolveGlobalFetchProxyConfig() {
    const httpProxy = (0, proxy_env_1.getProxyResolution)(false, process.env, {
        allowedProtocols: FETCH_PROXY_PROTOCOLS,
    });
    const httpsProxy = (0, proxy_env_1.getProxyResolution)(true, process.env, {
        allowedProtocols: FETCH_PROXY_PROTOCOLS,
    });
    return {
        httpProxyUrl: httpProxy.url,
        httpsProxyUrl: httpsProxy.url,
        error: httpProxy.error ?? httpsProxy.error,
    };
}
//# sourceMappingURL=fetch-proxy-setup.js.map