"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const npmConfLoader = require("npm-conf");
const url = require("url");
const proxy_errors_1 = require("./proxy-errors");
const proxy_settings_1 = require("./proxy-settings");
const validate_1 = require("./validate");
const winreg_1 = require("./winreg");
const npmConf = npmConfLoader();
function getProxySettings() {
    return __awaiter(this, void 0, void 0, function* () {
        const envProxy = getEnvProxy();
        if (envProxy) {
            return envProxy;
        }
        if (process.platform === "win32") {
            return getProxyWindows();
        }
        else {
            return null;
        }
    });
}
exports.getProxySettings = getProxySettings;
function getAndTestProxySettings(login) {
    return __awaiter(this, void 0, void 0, function* () {
        const settings = yield getProxySettings();
        if (!settings) {
            return;
        }
        try {
            yield validate_1.validateProxySetting(settings.http);
        }
        catch (e) {
            // Proxy authentication required
            if (e instanceof proxy_errors_1.ProxyAuthenticationRequiredError) {
                if (!login) {
                    throw e;
                }
                const credentials = yield login();
                settings.http.credentials = credentials;
                settings.https.credentials = credentials;
                yield validate_1.validateProxySetting(settings.http);
            }
            else {
                throw e;
            }
        }
        return settings;
    });
}
exports.getAndTestProxySettings = getAndTestProxySettings;
exports.default = getProxySettings;
function getProxyWindows() {
    return __awaiter(this, void 0, void 0, function* () {
        // HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
        const values = yield winreg_1.openKey(winreg_1.Hive.HKCU, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
        const proxy = values["ProxyServer"];
        const enable = values["ProxyEnable"];
        const enableValue = Number(enable && enable.value);
        if (enableValue > 0 && proxy) {
            return parseWindowsProxySetting(proxy.value);
        }
        else {
            return null;
        }
    });
}
exports.getProxyWindows = getProxyWindows;
/**
 * Return proxy settings defined in the environment.
 * This can be either as HTTP(s)_PROXY environment variable or in the npm config
 */
function getEnvProxy() {
    const httpsProxy = process.env.HTTPS_PROXY ||
        process.env.https_proxy ||
        npmConf.get("https-proxy") ||
        npmConf.get("proxy") ||
        null;
    const httpProxy = process.env.HTTP_PROXY ||
        process.env.http_proxy ||
        npmConf.get("http-proxy") ||
        npmConf.get("proxy") ||
        null;
    if (!httpProxy && !httpsProxy) {
        return null;
    }
    return { http: new proxy_settings_1.ProxySetting(httpProxy), https: new proxy_settings_1.ProxySetting(httpsProxy) };
}
exports.getEnvProxy = getEnvProxy;
function parseWindowsProxySetting(proxySetting) {
    if (!proxySetting) {
        return null;
    }
    if (isValidUrl(proxySetting)) {
        const setting = new proxy_settings_1.ProxySetting(proxySetting);
        return {
            http: setting,
            https: setting,
        };
    }
    const settings = proxySetting.split(";").map(x => x.split("=", 2));
    const result = {};
    for (const [key, value] of settings) {
        if (value) {
            result[key] = new proxy_settings_1.ProxySetting(value);
        }
    }
    return processResults(result);
}
exports.parseWindowsProxySetting = parseWindowsProxySetting;
function isValidUrl(value) {
    const obj = url.parse(value);
    return Boolean(obj.hostname);
}
function processResults(results) {
    const { http, https } = results;
    if (http && https) {
        return { http, https };
    }
    else if (http) {
        return { http, https: http };
    }
    else if (https) {
        return { http: https, https };
    }
    else {
        return null;
    }
}
//# sourceMappingURL=proxy.js.map