"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    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) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AutodiscoverService = void 0;
const ArgumentException_1 = require("../Exceptions/ArgumentException");
const AutodiscoverDnsClient_1 = require("./AutodiscoverDnsClient");
const AutodiscoverEndpoints_1 = require("../Enumerations/AutodiscoverEndpoints");
const AutodiscoverErrorCode_1 = require("../Enumerations/AutodiscoverErrorCode");
const AutodiscoverLocalException_1 = require("../Exceptions/AutodiscoverLocalException");
const AutodiscoverRequest_1 = require("./Requests/AutodiscoverRequest");
const EwsLogging_1 = require("../Core/EwsLogging");
const EwsUtilities_1 = require("../Core/EwsUtilities");
const ExchangeVersion_1 = require("../Enumerations/ExchangeVersion");
const GetDomainSettingsRequest_1 = require("./Requests/GetDomainSettingsRequest");
const GetUserSettingsRequest_1 = require("./Requests/GetUserSettingsRequest");
const OAuthCredentials_1 = require("../Credentials/OAuthCredentials");
const PartnerTokenCredentials_1 = require("../Credentials/PartnerTokenCredentials");
const ServiceValidationException_1 = require("../Exceptions/ServiceValidationException");
const ServiceVersionException_1 = require("../Exceptions/ServiceVersionException");
const ExtensionMethods_1 = require("../ExtensionMethods");
const Strings_1 = require("../Strings");
const TraceFlags_1 = require("../Enumerations/TraceFlags");
const Uri_1 = require("../Uri");
const WindowsLiveCredentials_1 = require("../Credentials/WindowsLiveCredentials");
const X509CertificateCredentials_1 = require("../Credentials/X509CertificateCredentials");
const ExchangeServiceBase_1 = require("../Core/ExchangeServiceBase");
/**
 * Represents a binding to the Exchange Autodiscover Service.
 * @sealed
 */
class AutodiscoverService extends ExchangeServiceBase_1.ExchangeServiceBase {
    constructor(domainUrlServiceOrVersion = null, domainOrVersion = null, version = ExchangeVersion_1.ExchangeVersion.Exchange2010) {
        const argsLength = arguments.length;
        if (argsLength > 3) {
            throw new Error("AutodiscoverService.ts - ctor with " + argsLength + " parameters, invalid number of arguments, check documentation and try again.");
        }
        let service = null;
        let domain = null;
        let url = null;
        let requestedServerVersion = version;
        let hasService = false;
        let hasVersion = false;
        if (argsLength >= 1) {
            if (domainUrlServiceOrVersion instanceof Uri_1.Uri) {
                url = domainUrlServiceOrVersion;
            }
            else if (domainUrlServiceOrVersion instanceof ExchangeServiceBase_1.ExchangeServiceBase) {
                service = domainUrlServiceOrVersion;
                hasService = true;
            }
            else if (typeof domainUrlServiceOrVersion === 'string') {
                domain = domainUrlServiceOrVersion;
            }
            else if (typeof domainUrlServiceOrVersion === 'number') {
                requestedServerVersion = domainUrlServiceOrVersion;
                hasVersion = true;
            }
        }
        if (argsLength >= 2) {
            if (typeof domainOrVersion === 'string') {
                if (!(domainUrlServiceOrVersion instanceof Uri_1.Uri)) {
                    throw new Error("AutodiscoverService.ts - ctor with " + argsLength + " parameters - incorrect uses of parameter at 1st position, it must be Uri when using string at 2nd place");
                }
                domain = domainOrVersion;
            }
            else if (typeof domainOrVersion === 'number') {
                requestedServerVersion = domainOrVersion;
            }
        }
        if ((0, ExtensionMethods_1.hasValue)(service)) {
            super(service, requestedServerVersion);
        }
        else {
            EwsUtilities_1.EwsUtilities.ValidateDomainNameAllowNull(domain, "domain");
            super(requestedServerVersion);
            this.url = url;
            this.domain = domain;
        }
        this.dnsClient = new AutodiscoverDnsClient_1.AutodiscoverDnsClient(this);
        this.isExternal = true;
        this.enableScpLookup = false; // ref: no SCP for nodejs yet.
    }
    /**
     *  Set Autodiscover hard coded url for Office 365, useful in GCC and O365 in China. This is also helpful if O365 need changing url for some reason (beta testing, transition to different url), no need to update lib
     *
     * @static
     * @type {string}
     */
    static get Office365AutodiscoverUrl() {
        return this.o365AutodiscoverUrl;
    }
    static set Office365AutodiscoverUrl(value) {
        this.o365AutodiscoverUrl = value;
    }
    /**
     *  Set Autodiscover hard coded check for header when it is auto redirected (skip 302 and follow the redirect in lib, likely browsers)
     *
     * @static
     * @type {string}
     */
    static get Office365AutodiscoverRedirectHeader() {
        return this.o365AutodiscoverRedirectHeader;
    }
    static set Office365AutodiscoverRedirectHeader(value) {
        this.o365AutodiscoverRedirectHeader = value;
    }
    /**
     *  Set Autodiscover hard coded check for header value when it is auto redirected (skip 302 and follow the redirect in lib, likely browsers)
     *
     * @static
     * @type {string}
     */
    static get Office365AutodiscoverRedirectHeaderValue() {
        return this.o365AutodiscoverRedirectHeaderValue;
    }
    static set Office365AutodiscoverRedirectHeaderValue(value) {
        this.o365AutodiscoverRedirectHeaderValue = value;
    }
    //#endregion
    //#region Properties | Getter/Setter
    get Domain() {
        return this.domain;
    }
    set Domain(value) {
        this.domain = value;
        if (value)
            this.url = undefined;
    }
    get Url() {
        return this.url;
    }
    set Url(value) {
        this.url = value;
    }
    get IsExternal() {
        return this.isExternal;
    }
    set IsExternal(value) {
        this.isExternal = value;
    }
    get RedirectionUrlValidationCallback() {
        return this.redirectionUrlValidationCallback;
    }
    set RedirectionUrlValidationCallback(value) {
        this.redirectionUrlValidationCallback = value;
    }
    get DnsServerAddress() {
        return this.dnsServerAddress;
    }
    set DnsServerAddress(value) {
        this.dnsServerAddress = value;
    }
    get EnableScpLookup() {
        return this.enableScpLookup;
    }
    set EnableScpLookup(value) {
        this.enableScpLookup = value;
    }
    /**
     * Calls the redirection URL validation callback.
     *
     * @remark  If the redirection URL validation callback is null, use the default callback which does not allow following any redirections.
     * @param   {string}    redirectionUrl   The redirection URL.
     * @return  {boolean}   True if redirection should be followed.
     */
    CallRedirectionUrlValidationCallback(redirectionUrl) {
        var callback = (this.RedirectionUrlValidationCallback == null)
            ? this.DefaultAutodiscoverRedirectionUrlValidationCallback
            : this.RedirectionUrlValidationCallback;
        return callback(redirectionUrl);
    }
    /**
     * Default implementation of AutodiscoverRedirectionUrlValidationCallback. Always returns true indicating that the URL can be used.
    *
    * @param   {string}     redirectionUrl   The redirection URL.
    * @return  {boolean}    Returns true.
    */
    DefaultAutodiscoverRedirectionUrlValidationCallback(redirectionUrl) {
        throw new AutodiscoverLocalException_1.AutodiscoverLocalException(ExtensionMethods_1.StringHelper.Format("Autodiscover redirection is blocked for url: {0}" /*Strings.AutodiscoverRedirectBlocked*/, redirectionUrl));
    }
    /**
     * Defaults the get autodiscover service urls for domain.
     *
     * @param   {string}    domainName   Name of the domain.
     * @return  {string[]}  [description]
     */
    DefaultGetScpUrlsForDomain(domainName) { return []; } // System.Collections.Generic.ICollection<string>{ throw new Error("AutodiscoverService.ts - DefaultGetScpUrlsForDomain : Not implemented.");}
    /**
     * Disables SCP lookup if duplicate email address redirection.
     *
     * @param   {string}    emailAddress                The email address to use.
     * @param   {string[]}  redirectionEmailAddresses   The list of prior redirection email addresses.
     */
    DisableScpLookupIfDuplicateRedirection(emailAddress, redirectionEmailAddresses) {
        // SMTP addresses are case-insensitive so entries are converted to lower-case.
        emailAddress = emailAddress.toLowerCase();
        if (redirectionEmailAddresses.includes(emailAddress)) {
            this.EnableScpLookup = false;
        }
        else {
            redirectionEmailAddresses.push(emailAddress);
        }
    }
    /**
     * Gets the autodiscover endpoint URL.
     *
     * @param   {string}   host   The host.
     * @return  {Promise<Uri>}  [description]
     */
    GetAutodiscoverEndpointUrl(host) {
        return __awaiter(this, void 0, void 0, function* () {
            const autodiscoverUrlOut = { outValue: null };
            if (yield this.TryGetAutodiscoverEndpointUrl(host, autodiscoverUrlOut)) {
                return autodiscoverUrlOut.outValue;
            }
            else {
                throw new AutodiscoverLocalException_1.AutodiscoverLocalException(Strings_1.Strings.NoSoapOrWsSecurityEndpointAvailable);
            }
        });
    }
    /**
     * @internal Gets the list of autodiscover service hosts.
     *
     * @param   {string}            domainName     Name of the domain.
     * @param   {IOutParam<number>} scpHostCount   Count of SCP hosts that were found.
     * @return  {string[]}          List of host names.
     */
    GetAutodiscoverServiceHosts(domainName, scpHostCount) {
        var serviceHosts = [];
        var urls = this.GetAutodiscoverServiceUrls(domainName, scpHostCount);
        for (var url of urls) {
            serviceHosts.push(ExtensionMethods_1.UriHelper.getHost(url));
        }
        return serviceHosts;
    }
    /**
     * @internal Gets the list of autodiscover service URLs.
     *
     * @param   {string}            domainName     Domain name.
     * @param   {IOutParam<number>} scpHostCount   Count of hosts found via SCP lookup.
     * @return  {string[]}          List of Autodiscover URLs.
     */
    GetAutodiscoverServiceUrls(domainName, scpHostCount) {
        var urls = [];
        if (this.EnableScpLookup) {
            // Get SCP URLs
            //Func < string, ICollection <string>> callback = this.GetScpUrlsForDomainCallback ?? this.DefaultGetScpUrlsForDomain;
            //ICollection < string> scpUrls = callback(domainName);
            //foreach(string str in scpUrls)
            //{
            //    urls.Add(new Uri(str));
            //}
        }
        //scpHostCount = urls.length;
        // As a fallback, add autodiscover URLs base on the domain name.
        urls.push(ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverLegacyHttpsUrl, `autodiscover.${domainName}`)); // hard coding for autodiscover domain name
        urls.push(ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverLegacyHttpsUrl, domainName));
        return urls;
    }
    GetDomainSettings(domainOrDomains, requestedVersion, ...settings) {
        return __awaiter(this, void 0, void 0, function* () {
            let domains;
            let isCollection = true;
            domains = domainOrDomains;
            if (!Array.isArray(domainOrDomains)) {
                domains = [domainOrDomains];
                isCollection = false;
            }
            EwsUtilities_1.EwsUtilities.ValidateParam(domains, "domains");
            EwsUtilities_1.EwsUtilities.ValidateParam(settings, "settings");
            const result = yield this.GetSettings(domains, settings, requestedVersion, this.InternalGetDomainSettings.bind(this), () => { return domains[0]; });
            if (isCollection) {
                return result;
            }
            else {
                return result.__thisIndexer(0);
            }
        });
    }
    /**
     * Gets the endpoints from HTTP web response.
     *
     * @param   {XMLHttpRequest}   response   The response.
     * @return  {AutodiscoverEndpoints}              Endpoints enabled.
     */
    GetEndpointsFromHttpWebResponse(response) {
        var endpoints = AutodiscoverEndpoints_1.AutodiscoverEndpoints.Legacy;
        if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(response.getResponseHeader(AutodiscoverService.AutodiscoverSoapEnabledHeaderName))) {
            endpoints |= AutodiscoverEndpoints_1.AutodiscoverEndpoints.Soap;
        }
        if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(response.getResponseHeader(AutodiscoverService.AutodiscoverWsSecurityEnabledHeaderName))) {
            endpoints |= AutodiscoverEndpoints_1.AutodiscoverEndpoints.WsSecurity;
        }
        if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(response.getResponseHeader(AutodiscoverService.AutodiscoverWsSecuritySymmetricKeyEnabledHeaderName))) {
            endpoints |= AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecuritySymmetricKey;
        }
        if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(response.getResponseHeader(AutodiscoverService.AutodiscoverWsSecurityX509CertEnabledHeaderName))) {
            endpoints |= AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecurityX509Cert;
        }
        if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(response.getResponseHeader(AutodiscoverService.AutodiscoverOAuthEnabledHeaderName))) {
            endpoints |= AutodiscoverEndpoints_1.AutodiscoverEndpoints.OAuth;
        }
        return endpoints;
    }
    //GetLegacyUserSettings(emailAddress: string): any{ throw new Error("AutodiscoverService.ts - GetLegacyUserSettings : Not implemented.");}
    //GetLegacyUserSettingsAtUrl(emailAddress: string, url: Uri): any{ throw new Error("AutodiscoverService.ts - GetLegacyUserSettingsAtUrl : Not implemented.");}
    /**
     * @internal Get an autodiscover SRV record in DNS and construct autodiscover URL.
     *
     * @param   {string}   domainName   Name of the domain.
     * @return  {Promise<Uri>}                Autodiscover URL (may be null if lookup failed)
     */
    GetRedirectionUrlFromDnsSrvRecord(domainName) {
        return __awaiter(this, void 0, void 0, function* () {
            this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Trying to get Autodiscover host from DNS SRV record for {0}.", domainName));
            const hostname = yield this.dnsClient.FindAutodiscoverHostFromSrv(domainName);
            if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(hostname)) {
                this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Autodiscover host {0} was returned.", hostname));
                return new Uri_1.Uri(ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverLegacyHttpsUrl, hostname));
            }
            else {
                this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, "No matching Autodiscover DNS SRV records were found.");
                return null;
            }
        });
    }
    /**
     * Gets a redirection URL to an SSL-enabled Autodiscover service from the standard non-SSL Autodiscover URL.
     *
     * @param   {string}   domainName   The name of the domain to call Autodiscover on.
     * @return  {Promise<Uri>}                A valid SSL-enabled redirection URL. (May be null).
     */
    GetRedirectUrl(domainName) {
        return __awaiter(this, void 0, void 0, function* () {
            var url = ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverLegacyHttpUrl, "autodiscover." + domainName);
            this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Trying to get Autodiscover redirection URL from {0}.", url));
            var xhrOptions = {
                type: "GET",
                url: url,
                allowRedirect: false,
            };
            let response = null;
            try {
                response = yield this.XHRApi.xhr(xhrOptions);
            }
            catch (responseError) {
                if (responseError.status === 0) {
                    //catch (IOException ex)
                    this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("I/O error: {0}", "unable to connect"));
                    return null;
                }
                this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Request error: {0}", responseError.message || responseError.statusText || responseError.status));
                response = responseError;
            }
            if (response != null) {
                const redirectUrl = { outValue: null };
                if (this.TryGetRedirectionResponse(response, redirectUrl)) {
                    return redirectUrl.outValue;
                }
                // hard check for redirected office 365 url
                this.TraceMessage(TraceFlags_1.TraceFlags.All, "***hard checking for office 365 with node.js http request and presence of header x-federationtrusttokenissueruri= urn:federation:MicrosoftOnline");
                if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(response.getResponseHeader(AutodiscoverService.Office365AutodiscoverRedirectHeader))) {
                    if (response.getResponseHeader(AutodiscoverService.Office365AutodiscoverRedirectHeader) === AutodiscoverService.Office365AutodiscoverRedirectHeaderValue)
                        redirectUrl.outValue = new Uri_1.Uri(AutodiscoverService.Office365AutodiscoverUrl);
                    return redirectUrl.outValue;
                }
            }
            this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, "No Autodiscover redirection URL was returned.");
            return null;
        });
    }
    /**
     * Gets user or domain settings using Autodiscover SOAP service.
     *
     * @typeparam {TGetSettingsResponseCollection}  Type of response collection to return.
     * @typeparam {TSettingName}                    Type of setting name.
     *
     * @param   {string[]}                                                          identities          Either the domains or the SMTP addresses of the users.
     * @param   {settings: TSettingName[]}                                          settings            The settings.
     * @param   {ExchangeVersion}                                                   requestedVersion    Requested version of the Exchange service.
     * @param   {GetSettingsMethod<TGetSettingsResponseCollection, TSettingName>}   getSettingsMethod   The method to use.
     * @param   {() => string}                                                      getDomainMethod     The method to calculate the domain value.
     * @return  {Promise<TGetSettingsResponseCollection>}                           [description]
     */
    GetSettings(identities, settings, requestedVersion, getSettingsMethod, getDomainMethod) {
        return __awaiter(this, void 0, void 0, function* () {
            // Autodiscover service only exists in E14 or later.
            if (this.RequestedServerVersion < AutodiscoverService.MinimumRequestVersionForAutoDiscoverSoapService) {
                throw new ServiceVersionException_1.ServiceVersionException(ExtensionMethods_1.StringHelper.Format(Strings_1.Strings.AutodiscoverServiceIncompatibleWithRequestVersion, AutodiscoverService.MinimumRequestVersionForAutoDiscoverSoapService));
            }
            let response = null;
            let urlRef = null;
            let autodiscoverUrlRef = { getValue: () => urlRef, setValue: (url) => urlRef = url };
            // If Url is specified, call service directly.
            if (this.Url != null) {
                urlRef = this.url;
                response = yield getSettingsMethod(identities, settings, requestedVersion, autodiscoverUrlRef);
                this.Url = urlRef;
                return response;
            }
            else if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(this.Domain)) { // If Domain is specified, determine endpoint Url and call service.
                urlRef = yield this.GetAutodiscoverEndpointUrl(this.Domain);
                response = yield getSettingsMethod(identities, settings, requestedVersion, autodiscoverUrlRef);
                // If we got this far, response was successful, set Url.
                this.Url = urlRef;
                return response;
            }
            else { // No Url or Domain specified, need to figure out which endpoint(s) to try.
                // Assume caller is not inside the Intranet, regardless of whether SCP Urls
                // were returned or not. SCP Urls are only relevent if one of them returns
                // valid Autodiscover settings.
                this.IsExternal = true;
                let autodiscoverUrlOut = { outValue: null };
                autodiscoverUrlRef = { getValue: () => autodiscoverUrlOut.outValue, setValue: (url) => { autodiscoverUrlOut.outValue = url; } };
                let domainName = getDomainMethod();
                let scpHostCount = { outValue: 0 };
                let hosts = this.GetAutodiscoverServiceHosts(domainName, scpHostCount);
                if (hosts.length == 0) {
                    throw new ServiceValidationException_1.ServiceValidationException(Strings_1.Strings.AutodiscoverServiceRequestRequiresDomainOrUrl);
                }
                for (let currentHostIndex = 0; currentHostIndex < hosts.length; currentHostIndex++) {
                    const host = hosts[currentHostIndex];
                    const isScpHost = currentHostIndex < scpHostCount.outValue;
                    if (yield this.TryGetAutodiscoverEndpointUrl(host, autodiscoverUrlOut)) {
                        try {
                            response = yield getSettingsMethod(identities, settings, requestedVersion, autodiscoverUrlRef);
                            // If we got this far, the response was successful, set Url.
                            this.Url = autodiscoverUrlOut.outValue;
                            // Not external if Autodiscover endpoint found via SCP returned the settings.
                            if (isScpHost) {
                                this.IsExternal = false;
                            }
                            return response;
                        }
                        catch (error) {
                            // skip
                        }
                    }
                }
                this.TraceMessage(TraceFlags_1.TraceFlags.DebugMessage, "[Next-to-last chance: for autodiscover redirect] --hard checking for office 365 with node.js http request and presence of header x-federationtrusttokenissueruri: urn:federation:MicrosoftOnline. All other redirection wil fail");
                // Next-to-last chance: try unauthenticated GET over HTTP to be redirected to appropriate service endpoint.
                const autodiscoverUrl = { outValue: null };
                autodiscoverUrl.outValue = yield this.GetRedirectUrl(domainName);
                autodiscoverUrlRef = { getValue: () => autodiscoverUrl.outValue, setValue: (url) => { autodiscoverUrl.outValue = url; } };
                if ((autodiscoverUrl.outValue != null) &&
                    this.CallRedirectionUrlValidationCallback(autodiscoverUrl.outValue.ToString()) &&
                    (yield this.TryGetAutodiscoverEndpointUrl(autodiscoverUrl.outValue.Host, autodiscoverUrl))) {
                    const response = yield getSettingsMethod(identities, settings, requestedVersion, { getValue: () => autodiscoverUrl.outValue });
                    // If we got this far, response was successful, set Url.
                    this.Url = autodiscoverUrl.outValue;
                    return response;
                }
                // Last Chance: try to read autodiscover SRV Record from DNS. If we find one, use
                // the hostname returned to construct an Autodiscover endpoint URL.
                autodiscoverUrl.outValue = yield this.GetRedirectionUrlFromDnsSrvRecord(domainName);
                if ((autodiscoverUrl.outValue != null) &&
                    this.CallRedirectionUrlValidationCallback(autodiscoverUrl.outValue.ToString()) &&
                    (yield this.TryGetAutodiscoverEndpointUrl(autodiscoverUrl.outValue.Host, autodiscoverUrl))) {
                    response = yield getSettingsMethod(identities, settings, requestedVersion, autodiscoverUrlRef);
                    // If we got this far, the response was successful, set Url.
                    this.Url = autodiscoverUrl.outValue;
                    return response;
                }
                // else block not needed, if we get this far that mean no autodiscover url can be located
                throw new AutodiscoverLocalException_1.AutodiscoverLocalException(Strings_1.Strings.AutodiscoverCouldNotBeLocated);
            }
        });
    }
    GetUserSettings(smtpAddresses, userSettings) {
        return __awaiter(this, void 0, void 0, function* () {
            if ((0, ExtensionMethods_1.isNullOrUndefined)(userSettings) || (0, ExtensionMethods_1.isNullOrUndefined)(userSettings)) {
                throw new ArgumentException_1.ArgumentException(`AutodiscoverService.ts - GetUserSettings - Required parameters missing`);
            }
            if (Array.isArray(smtpAddresses)) {
                EwsUtilities_1.EwsUtilities.ValidateParam(smtpAddresses, "smtpAddresses");
                EwsUtilities_1.EwsUtilities.ValidateParam(userSettings, "settings");
                return this.GetSettings(smtpAddresses, userSettings, null, this.InternalGetUserSettings.bind(this), () => { return EwsUtilities_1.EwsUtilities.DomainFromEmailAddress(smtpAddresses[0]); });
            }
            var userSmtpAddress = smtpAddresses;
            if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(userSmtpAddress)) {
                throw new ServiceValidationException_1.ServiceValidationException(Strings_1.Strings.InvalidAutodiscoverSmtpAddress);
            }
            var requestedSettings = userSettings || [];
            if (requestedSettings.length == 0) {
                throw new ServiceValidationException_1.ServiceValidationException(Strings_1.Strings.InvalidAutodiscoverSettingsCount);
            }
            if (this.RequestedServerVersion < AutodiscoverService.MinimumRequestVersionForAutoDiscoverSoapService) {
                return this.InternalGetLegacyUserSettings(userSmtpAddress, requestedSettings);
            }
            else {
                return this.InternalGetSoapUserSettings(userSmtpAddress, requestedSettings);
            }
        });
    }
    /**
     * Retrieves the specified settings for a set of users.
     *
     * @param   {string[]}              userSmtpAddresses   The SMTP addresses of the users.
     * @param   {...UserSettingName[]}  userSettingNames    The user setting names.
     * @return  {Promise<GetUserSettingsResponseCollection>}    A GetUserSettingsResponseCollection object containing the responses for each individual user.
     */
    GetUsersSettings(userSmtpAddresses, ...userSettingNames) {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.RequestedServerVersion < AutodiscoverService.MinimumRequestVersionForAutoDiscoverSoapService) {
                throw new ServiceVersionException_1.ServiceVersionException(ExtensionMethods_1.StringHelper.Format(Strings_1.Strings.AutodiscoverServiceIncompatibleWithRequestVersion, AutodiscoverService.MinimumRequestVersionForAutoDiscoverSoapService));
            }
            return this.GetUserSettings(userSmtpAddresses, userSettingNames); //calls getsettings
        });
    }
    /**
     * Gets settings for one or more domains.
     *
     * @param   {string[]}              domains            The domains.
     * @param   {DomainSettingName[]}   settings           The settings.
     * @param   {ExchangeVersion}       requestedVersion   Requested version of the Exchange service.
     * @param   {IRefParam<Uri>}        autodiscoverUrl    The autodiscover URL.
     * @return  {AutodiscoverService}   GetDomainSettingsResponse collection.
     */
    InternalGetDomainSettings(domains, settings, requestedVersion, autodiscoverUrlRef) {
        return __awaiter(this, void 0, void 0, function* () {
            // The response to GetDomainSettings can be a redirection. Execute GetDomainSettings until we get back 
            // a valid response or we've followed too many redirections.
            for (let currentHop = 0; currentHop < AutodiscoverService.AutodiscoverMaxRedirections; currentHop++) {
                //BUG  - Typescript bug, reference for "this" inside multiple layers of IPromise points to global this object;
                //(may be not) - this functional is called as delegate under Promise chaining, loss poiters to this.
                //var request: GetUserSettingsRequest = new GetUserSettingsRequest(this, autodiscoverUrlRef.refvalue);
                var request = new GetDomainSettingsRequest_1.GetDomainSettingsRequest(this, autodiscoverUrlRef.getValue());
                request.Domains = domains;
                request.Settings = settings;
                request.RequestedVersion = requestedVersion;
                const response = yield request.Execute();
                // Did we get redirected?
                if (response.ErrorCode == AutodiscoverErrorCode_1.AutodiscoverErrorCode.RedirectUrl && response.RedirectionUrl != null) {
                    autodiscoverUrlRef.setValue(response.RedirectionUrl);
                }
                else {
                    return response;
                }
            }
            this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Maximum number of redirection hops {0} exceeded", AutodiscoverService.AutodiscoverMaxRedirections));
            throw new AutodiscoverLocalException_1.AutodiscoverLocalException(Strings_1.Strings.MaximumRedirectionHopsExceeded);
        });
    }
    InternalGetLegacyUserSettings(emailAddress, requestedSettings) {
        return __awaiter(this, void 0, void 0, function* () {
            throw new Error("Not implemented.");
        });
    }
    InternalGetLegacyUserSettingsPrivate(emailAddress, redirectionEmailAddresses, currentHop) {
        throw new Error("Not implemented.");
    }
    /**
     * @internal Calls the SOAP Autodiscover service for user settings for a single SMTP address.
     *
     * @param   {string}            smtpAddress         SMTP address.
     * @param   {UserSettingName[]} requestedSettings   The requested settings.
     * @return  {Promise<GetUserSettingsResponse>}                       [description]
     */
    InternalGetSoapUserSettings(smtpAddress, requestedSettings) {
        return __awaiter(this, void 0, void 0, function* () {
            const smtpAddresses = [smtpAddress];
            const redirectionEmailAddresses = [smtpAddress.toLowerCase()];
            for (let currentHop = 0; currentHop < AutodiscoverService.AutodiscoverMaxRedirections; currentHop++) {
                const response = (yield this.GetUserSettings(smtpAddresses, requestedSettings)).Responses[0];
                // const responses: GetUserSettingsResponseCollection = await this.GetUserSettings(smtpAddresses, requestedSettings);
                // const response: GetUserSettingsResponse =responses[0];
                switch (response.ErrorCode) {
                    case AutodiscoverErrorCode_1.AutodiscoverErrorCode.RedirectAddress:
                        this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverResponse, ExtensionMethods_1.StringHelper.Format("Autodiscover service returned redirection email address '{0}'.", response.RedirectTarget));
                        smtpAddresses.splice(0);
                        smtpAddresses.push(response.RedirectTarget.toLowerCase());
                        this.Url = null;
                        this.Domain = null;
                        // If this email address was already tried, we may have a loop
                        // in SCP lookups. Disable consideration of SCP records.
                        this.ThrowIfDuplicateRedirection(response.RedirectTarget, { getValue: () => redirectionEmailAddresses });
                        break;
                    case AutodiscoverErrorCode_1.AutodiscoverErrorCode.RedirectUrl:
                        this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverResponse, ExtensionMethods_1.StringHelper.Format("Autodiscover service returned redirection URL '{0}'.", response.RedirectTarget));
                        this.Url = this.Credentials.AdjustUrl(new Uri_1.Uri(response.RedirectTarget));
                        break;
                    case AutodiscoverErrorCode_1.AutodiscoverErrorCode.NoError:
                    default:
                        return response;
                }
            }
            throw new AutodiscoverLocalException_1.AutodiscoverLocalException(Strings_1.Strings.AutodiscoverCouldNotBeLocated);
        });
    }
    /**
     * Gets settings for one or more users.
     *
     * @param   {string[]}            smtpAddresses      The SMTP addresses of the users.
     * @param   {UserSettingName[]}   settings           The settings.
     * @param   {ExchangeVersion}     requestedVersion   Requested version of the Exchange service.
     * @param   {IRefParam<Uri>}      autodiscoverUrl    The autodiscover URL.
     * @return  {Promise<GetUserSettingsResponseCollection>}                      GetUserSettingsResponse collection.
     */
    InternalGetUserSettings(smtpAddresses, settings, requestedVersion, autodiscoverUrlRef) {
        return __awaiter(this, void 0, void 0, function* () {
            // The response to GetUserSettings can be a redirection. Execute GetUserSettings until we get back
            // a valid response or we've followed too many redirections.
            for (let currentHop = 0; currentHop < AutodiscoverService.AutodiscoverMaxRedirections; currentHop++) {
                //BUG  - Typescript bug, reference for "this" inside multiple layers of IPromise points to global this object;
                //(may be not) - this functional is called as delegate under Promise chaining, loss poiters to this.
                //var request: GetUserSettingsRequest = new GetUserSettingsRequest(this, autodiscoverUrlRef.refvalue);
                var request = new GetUserSettingsRequest_1.GetUserSettingsRequest(this, autodiscoverUrlRef.getValue());
                request.SmtpAddresses = smtpAddresses;
                request.Settings = settings;
                const response = yield request.Execute();
                // Did we get redirected?
                if (response.ErrorCode == AutodiscoverErrorCode_1.AutodiscoverErrorCode.RedirectUrl && response.RedirectionUrl != null) {
                    this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Request to {0} returned redirection to {1}", autodiscoverUrlRef.getValue().ToString(), response.RedirectionUrl.ToString()));
                    // this url need be brought back to the caller.
                    //
                    autodiscoverUrlRef.setValue(response.RedirectionUrl);
                }
                else {
                    return response;
                }
            }
            this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Maximum number of redirection hops {0} exceeded", AutodiscoverService.AutodiscoverMaxRedirections));
            throw new AutodiscoverLocalException_1.AutodiscoverLocalException(Strings_1.Strings.AutodiscoverCouldNotBeLocated);
        });
    }
    //PrepareHttpWebRequestForUrl(url: Uri): Data.IEwsHttpWebRequest{ throw new Error("AutodiscoverService.ts - PrepareHttpWebRequestForUrl : Not implemented.");}
    //ProcessHttpErrorResponse(httpWebResponse: Data.IEwsHttpWebResponse, webException: any): any{ throw new Error("AutodiscoverService.ts - ProcessHttpErrorResponse : Not implemented.");}
    ProcessHttpErrorResponse(httpWebResponse, webException) { /*throw new Error("Not implemented.")*/ ; }
    TraceResponse(response, memoryStream) {
        //todo: implement tracing
        //this.ProcessHttpResponseHeaders(TraceFlags.AutodiscoverResponseHttpHeaders, response);
        //if (this.TraceEnabled) {
        //    if (!StringHelper.IsNullOrEmpty(response.ContentType) &&
        //        (response.ContentType.StartsWith("text/", StringComparison.OrdinalIgnoreCase) ||
        //        response.ContentType.StartsWith("application/soap", StringComparison.OrdinalIgnoreCase))) {
        //        this.TraceXml(TraceFlags.AutodiscoverResponse, memoryStream);
        //    }
        //    else {
        //        this.TraceMessage(TraceFlags.AutodiscoverResponse, "Non-textual response");
        //    }
        //}
    }
    /**
     * Tries the get Autodiscover Service endpoint URL.
     *
     * @param   {string}          host   The host.
     * @param   {IOutParam<Uri>}  url    The URL.
     * @return  {Promise<boolean>}         [description]
     */
    TryGetAutodiscoverEndpointUrl(hostref, url) {
        return __awaiter(this, void 0, void 0, function* () {
            url.outValue = null;
            const endpointsOut = { outValue: AutodiscoverEndpoints_1.AutodiscoverEndpoints.None };
            let host = hostref;
            const hostRefParam = { getValue: () => host, setValue: (value) => { host = value; } };
            if (yield this.TryGetEnabledEndpointsForHost(hostRefParam, endpointsOut)) {
                // host = hostref;
                url.outValue = new Uri_1.Uri(ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverSoapHttpsUrl, host));
                const endpoints = endpointsOut.outValue;
                // Make sure that at least one of the non-legacy endpoints is available.
                if (((endpoints & AutodiscoverEndpoints_1.AutodiscoverEndpoints.Soap) != AutodiscoverEndpoints_1.AutodiscoverEndpoints.Soap) &&
                    ((endpoints & AutodiscoverEndpoints_1.AutodiscoverEndpoints.WsSecurity) != AutodiscoverEndpoints_1.AutodiscoverEndpoints.WsSecurity) &&
                    ((endpoints & AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecuritySymmetricKey) != AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecuritySymmetricKey) &&
                    ((endpoints & AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecurityX509Cert) != AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecurityX509Cert) &&
                    ((endpoints & AutodiscoverEndpoints_1.AutodiscoverEndpoints.OAuth) != AutodiscoverEndpoints_1.AutodiscoverEndpoints.OAuth)) {
                    this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("No Autodiscover endpoints are available  for host {0}", host));
                    return false;
                }
                // If we have WLID credentials, make sure that we have a WS-Security endpoint
                if (this.Credentials instanceof WindowsLiveCredentials_1.WindowsLiveCredentials) {
                    if ((endpoints & AutodiscoverEndpoints_1.AutodiscoverEndpoints.WsSecurity) != AutodiscoverEndpoints_1.AutodiscoverEndpoints.WsSecurity) {
                        this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("No Autodiscover WS-Security endpoint is available for host {0}", host));
                        return false;
                    }
                    else {
                        url.outValue = new Uri_1.Uri(ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverSoapWsSecurityHttpsUrl, host));
                    }
                }
                else if (this.Credentials instanceof PartnerTokenCredentials_1.PartnerTokenCredentials) {
                    if ((endpoints & AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecuritySymmetricKey) != AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecuritySymmetricKey) {
                        this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("No Autodiscover WS-Security/SymmetricKey endpoint is available for host {0}", host));
                        return false;
                    }
                    else {
                        url.outValue = new Uri_1.Uri(ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverSoapWsSecuritySymmetricKeyHttpsUrl, host));
                    }
                }
                else if (this.Credentials instanceof X509CertificateCredentials_1.X509CertificateCredentials) {
                    if ((endpoints & AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecurityX509Cert) != AutodiscoverEndpoints_1.AutodiscoverEndpoints.WSSecurityX509Cert) {
                        this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("No Autodiscover WS-Security/X509Cert endpoint is available for host {0}", host));
                        return false;
                    }
                    else {
                        url.outValue = new Uri_1.Uri(ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverSoapWsSecurityX509CertHttpsUrl, host));
                    }
                }
                else if (this.Credentials instanceof OAuthCredentials_1.OAuthCredentials) {
                    // If the credential is OAuthCredentials, no matter whether we have
                    // the corresponding x-header, we will go with OAuth.
                    url.outValue = new Uri_1.Uri(ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverSoapHttpsUrl, host));
                }
                return true;
            }
            else {
                this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("No Autodiscover endpoints are available for host {0}", host));
                return false;
            }
        });
    }
    /**
     * Gets the enabled autodiscover endpoints on a specific host.
     *
     * @param   {host: IRefParam<string>}   host        The host.
     * @param   {IOutParam<AutodiscoverEndpoints>}   endpoints   Endpoints found for host.
     */
    TryGetEnabledEndpointsForHost(host, endpoints) {
        return __awaiter(this, void 0, void 0, function* () {
            this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Determining which endpoints are enabled for host {0}", host.getValue()));
            // We may get redirected to another host. And therefore need to limit the number
            // of redirections we'll tolerate.
            for (let currentHop = 0; currentHop < AutodiscoverService.AutodiscoverMaxRedirections; currentHop++) {
                const autoDiscoverUrl = ExtensionMethods_1.StringHelper.Format(AutodiscoverService.AutodiscoverLegacyHttpsUrl, host.getValue());
                endpoints.outValue = AutodiscoverEndpoints_1.AutodiscoverEndpoints.None;
                var xhrOptions = {
                    type: "GET",
                    url: autoDiscoverUrl,
                    allowRedirect: false,
                };
                let response = null;
                try {
                    // try get response, in most cases this will not be a status 200.
                    response = yield this.XHRApi.xhr(xhrOptions);
                }
                catch (responseError) {
                    if (responseError.status === 0) {
                        //catch (IOException ex) and return false
                        this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("I/O error: {0}", "unable to connect"));
                        return false;
                    }
                    this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Request error: {0}", responseError.message || responseError.statusText || responseError.status));
                    // assign error to response
                    response = responseError;
                }
                if (response != null) {
                    // check redirect url if any for next hop
                    var redirectUrl = { outValue: null };
                    if (this.TryGetRedirectionResponse(response, redirectUrl)) {
                        this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Host returned redirection to host '{0}'", redirectUrl.outValue.Host));
                        host.setValue(redirectUrl.outValue.Host);
                    }
                    else {
                        endpoints.outValue = this.GetEndpointsFromHttpWebResponse(response);
                        this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Host returned enabled endpoint flags: {0}", ExtensionMethods_1.EnumHelper.ToString(AutodiscoverEndpoints_1.AutodiscoverEndpoints, endpoints.outValue)));
                        return true;
                        // hold it for bug reports, if not delete after few version later (0.10)
                        // if (resperr.status === 401) {
                        //   endpoints.outValue = this.GetEndpointsFromHttpWebResponse(resperr);
                        //   this.TraceMessage(
                        //     TraceFlags.AutodiscoverConfiguration,
                        //     StringHelper.Format("Host returned enabled endpoint flags: {0}", EnumHelper.ToString(AutodiscoverEndpoints, endpoints.outValue)));
                        //   return true;
                        // } else {
                        //   //catch (WebException ex)
                        //   this.TraceMessage(
                        //     TraceFlags.AutodiscoverConfiguration,
                        //     StringHelper.Format("Request error: {0}, {1}", resperr.status, resperr.statusText));
                        // }
                        // return false;
                    }
                }
                else {
                    return false;
                }
            }
            this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Maximum number of redirection hops {0} exceeded", AutodiscoverService.AutodiscoverMaxRedirections));
            throw new AutodiscoverLocalException_1.AutodiscoverLocalException(Strings_1.Strings.MaximumRedirectionHopsExceeded);
        });
    }
    ThrowIfDuplicateRedirection(emailAddress, redirectionEmailAddresses) {
        // SMTP addresses are case-insensitive so entries are converted to lower-case.
        emailAddress = emailAddress.toLowerCase();
        if (redirectionEmailAddresses.getValue().includes(emailAddress)) {
            //this.EnableScpLookup = false;
            throw new AutodiscoverLocalException_1.AutodiscoverLocalException("Detected redirection loop, Redirection address already tried");
        }
        else {
            var oldcount = redirectionEmailAddresses.getValue().length;
            redirectionEmailAddresses.getValue().push(emailAddress);
            if (oldcount === redirectionEmailAddresses.getValue().length) {
                throw new Error("AutodiscoverService.ts - error in ref param logic, need to fix array type getter");
            }
            EwsLogging_1.EwsLogging.Assert(false, "AutodiscoverService.ts - ThrowIfDuplicateRedirection", "AutodiscoverService.ts - array getter worked:), remove this message and throw statement");
        }
    }
    //TryGetPartnerAccess(targetTenantDomain: string, partnerAccessCredentials: any, targetTenantAutodiscoverUrl: any): boolean{ throw new Error("AutodiscoverService.ts - TryGetPartnerAccess : Not implemented.");}
    /**
     * Tries the get redirection response.
     *
     * @param   {XMLHttpRequest}  response      The response.
     * @param   {IOutParam<Uri>}  redirectUrl   The redirect URL.
     * @return  {boolean}         True if a valid redirection URL was found.
     */
    TryGetRedirectionResponse(response, redirectUrl) {
        redirectUrl.outValue = null;
        if (AutodiscoverRequest_1.AutodiscoverRequest.IsRedirectionResponse(response)) {
            // Get the redirect location and verify that it's valid.
            const location = response.getResponseHeader("Location"); // HttpResponseHeader.Location
            if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(location)) {
                try {
                    redirectUrl.outValue = new Uri_1.Uri(location);
                    // Check if URL is SSL and that the path matches.
                    const match = AutodiscoverService.LegacyPathRegex.test(redirectUrl.outValue.AbsoluteUri);
                    if ((redirectUrl.outValue.Scheme == Uri_1.Uri.UriSchemeHttps) &&
                        match) {
                        this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Redirection URL found: '{0}'", redirectUrl.outValue));
                        return true;
                    }
                }
                catch (UriFormatException) {
                    this.TraceMessage(TraceFlags_1.TraceFlags.AutodiscoverConfiguration, ExtensionMethods_1.StringHelper.Format("Invalid redirection URL was returned: '{0}'", location));
                    return false;
                }
            }
        }
        return false;
    }
}
exports.AutodiscoverService = AutodiscoverService;
//#region Static members
/**
 * Autodiscover legacy path
 *
 * @static
 */
AutodiscoverService.AutodiscoverLegacyPath = "/autodiscover/autodiscover.xml";
/**
 * Autodiscover legacy Url with protocol fill-in
 *
 * @static
 */
AutodiscoverService.AutodiscoverLegacyUrl = "{0}://{1}" + AutodiscoverService.AutodiscoverLegacyPath;
/**
 * Autodiscover legacy HTTPS Url
 *
 * @static
 */
AutodiscoverService.AutodiscoverLegacyHttpsUrl = "https://{0}" + AutodiscoverService.AutodiscoverLegacyPath;
/**
 * Autodiscover legacy HTTP Url
 *
 * @static
 */
AutodiscoverService.AutodiscoverLegacyHttpUrl = "http://{0}" + AutodiscoverService.AutodiscoverLegacyPath;
/**
 * Autodiscover SOAP HTTPS Url
 *
 * @static
 */
AutodiscoverService.AutodiscoverSoapHttpsUrl = "https://{0}/autodiscover/autodiscover.svc";
/**
 * Autodiscover SOAP WS-Security HTTPS Url
 *
 * @static
 */
AutodiscoverService.AutodiscoverSoapWsSecurityHttpsUrl = AutodiscoverService.AutodiscoverSoapHttpsUrl + "/wssecurity";
/**
 * Autodiscover SOAP WS-Security symmetrickey HTTPS Url
 *
 * @static
 */
AutodiscoverService.AutodiscoverSoapWsSecuritySymmetricKeyHttpsUrl = AutodiscoverService.AutodiscoverSoapHttpsUrl + "/wssecurity/symmetrickey";
/**
 * Autodiscover SOAP WS-Security x509cert HTTPS Url
 *
 * @static
 */
AutodiscoverService.AutodiscoverSoapWsSecurityX509CertHttpsUrl = AutodiscoverService.AutodiscoverSoapHttpsUrl + "/wssecurity/x509cert";
/**
 * Autodiscover request namespace
 *
 * @static
 */
AutodiscoverService.AutodiscoverRequestNamespace = "http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006";
/**
 * Legacy path regular expression.
 *
 * @static
 */
AutodiscoverService.LegacyPathRegex = new RegExp("\/autodiscover/([^/]+/)*autodiscover.xml");
/**
 * Maximum number of Url (or address) redirections that will be followed by an Autodiscover call
 *
 * @static
 */
AutodiscoverService.AutodiscoverMaxRedirections = 10;
/**
 * HTTP header indicating that SOAP Autodiscover service is enabled.
 *
 * @static
 */
AutodiscoverService.AutodiscoverSoapEnabledHeaderName = "X-SOAP-Enabled";
/**
 * HTTP header indicating that WS-Security Autodiscover service is enabled.
 *
 * @static
 */
AutodiscoverService.AutodiscoverWsSecurityEnabledHeaderName = "X-WSSecurity-Enabled";
/**
 * HTTP header indicating that WS-Security/SymmetricKey Autodiscover service is enabled.
 *
 * @static
 */
AutodiscoverService.AutodiscoverWsSecuritySymmetricKeyEnabledHeaderName = "X-WSSecurity-SymmetricKey-Enabled";
/**
 * HTTP header indicating that WS-Security/X509Cert Autodiscover service is enabled.
 *
 * @static
 */
AutodiscoverService.AutodiscoverWsSecurityX509CertEnabledHeaderName = "X-WSSecurity-X509Cert-Enabled";
/**
 * HTTP header indicating that OAuth Autodiscover service is enabled.
 *
 * @static
 */
AutodiscoverService.AutodiscoverOAuthEnabledHeaderName = "X-OAuth-Enabled";
/**
 * Minimum request version for Autodiscover SOAP service.
 *
 * @static
 */
AutodiscoverService.MinimumRequestVersionForAutoDiscoverSoapService = ExchangeVersion_1.ExchangeVersion.Exchange2010;
//#endregion
//#region static method for setting Office 365 specific autodiscover URl, can be used in O365 in China and govt community cloud
AutodiscoverService.o365AutodiscoverUrl = "https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc";
AutodiscoverService.o365AutodiscoverRedirectHeader = "x-federationtrusttokenissueruri";
AutodiscoverService.o365AutodiscoverRedirectHeaderValue = "urn:federation:MicrosoftOnline";
//class GetSettingsMethod<TGetSettingsResponseCollection, TSettingName> extends System.MulticastDelegate {
//    BeginInvoke(smtpAddresses: System.Collections.Generic.List<string>, settings: System.Collections.Generic.List<T>, requestedVersion: Data.ExchangeVersion, autodiscoverUrl: any, callback: System.AsyncCallback, object: any): System.IAsyncResult { throw new Error("AutodiscoverService.ts - BeginInvoke : Not implemented."); }
//    EndInvoke(autodiscoverUrl: any, result: System.IAsyncResult): TGetSettingsResponseCollection { throw new Error("AutodiscoverService.ts - EndInvoke : Not implemented."); }
//    Invoke(smtpAddresses: System.Collections.Generic.List<string>, settings: System.Collections.Generic.List<T>, requestedVersion: Data.ExchangeVersion, autodiscoverUrl: any): TGetSettingsResponseCollection { throw new Error("AutodiscoverService.ts - Invoke : Not implemented."); }
//}
// delete - function getAutodiscoverConstructorSuperParameters(
//     domainUrlServiceOrVersion: string | Uri | ExchangeServiceBase | ExchangeVersion = null,
//     domainOrVersion: string | ExchangeVersion = null,
//     version: ExchangeVersion = ExchangeVersion.Exchange2010
// ) {
//     const service: ExchangeServiceBase = domainUrlServiceOrVersion instanceof ExchangeServiceBase ? domainUrlServiceOrVersion : null;
//     let serviceVersion: ExchangeVersion = version;
//     if(service) {
//         serviceVersion = service.RequestedServerVersion;
//     }
//     if(typeof domainOrVersion === 'number') {
//         serviceVersion = domainOrVersion;
//     }
//     return { service, version };
// }
//# sourceMappingURL=AutodiscoverService.js.map