"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExchangeServiceBase = void 0;
const AccountIsLockedException_1 = require("../Exceptions/AccountIsLockedException");
const ArgumentException_1 = require("../Exceptions/ArgumentException");
const DateTime_1 = require("../DateTime");
const AltDictionary_1 = require("../AltDictionary");
const EwsLogging_1 = require("./EwsLogging");
const EwsTraceListener_1 = require("../Misc/EwsTraceListener");
const EwsUtilities_1 = require("./EwsUtilities");
const ExchangeVersion_1 = require("../Enumerations/ExchangeVersion");
const ServiceLocalException_1 = require("../Exceptions/ServiceLocalException");
const ServiceRequestUnauthorizedException_1 = require("../Exceptions/ServiceRequestUnauthorizedException");
const ExtensionMethods_1 = require("../ExtensionMethods");
const Strings_1 = require("../Strings");
const TimeZoneDefinition_1 = require("../ComplexProperties/TimeZones/TimeZoneDefinition");
const TimeZoneInfo_1 = require("../TimeZoneInfo");
const TraceFlags_1 = require("../Enumerations/TraceFlags");
const Uri_1 = require("../Uri");
const XHRFactory_1 = require("../XHRFactory");
/**
 * Represents an abstract binding to an Exchange Service.
 */
class ExchangeServiceBase {
    constructor(versionServiceorTZ, versionOrTZ) {
        //#region const members
        // private static lockObj: any = new Object();
        this.requestedServerVersion = ExchangeVersion_1.ExchangeVersion.Exchange2013_SP1;
        this.credentials = null;
        // private useDefaultCredentials: boolean = false;
        this.timeout = 100000;
        this.traceEnabled = false;
        this.sendClientLatencies = true;
        this.traceFlags = TraceFlags_1.TraceFlags.All;
        this.traceListener = new EwsTraceListener_1.EwsTraceListener();
        this.preAuthenticate = false;
        this.userAgent = ExchangeServiceBase.defaultUserAgent;
        this.acceptGzipEncoding = true;
        this.keepAlive = true;
        this.connectionGroupName = null;
        this.clientRequestId = null;
        this.returnClientRequestId = false;
        // private cookieContainer: CookieContainer = new CookieContainer();
        this.timeZone = TimeZoneInfo_1.TimeZoneInfo.Local;
        this.timeZoneDefinition = null;
        this.serverInfo = null;
        // private webProxy: IWebProxy = null;
        this.httpHeaders = new AltDictionary_1.DictionaryWithStringKey();
        this.httpResponseHeaders = new AltDictionary_1.DictionaryWithStringKey();
        // private ewsHttpWebRequestFactory: IEwsHttpWebRequestFactory = new EwsHttpWebRequestFactory();
        this.suppressXmlVersionHeader = false;
        //#endregion
        //#region EWS JavaScript code
        this.xhrApi = null;
        var argsLength = arguments.length;
        if (argsLength > 2) {
            throw new Error("ExchangeServiceBase.ts - ctor with " + argsLength + " parameters, invalid number of arguments, check documentation and try again.");
        }
        var timeZone = null;
        var requestedServerVersion = ExchangeVersion_1.ExchangeVersion.Exchange2013_SP1;
        var service = null;
        if (argsLength >= 1) {
            if (versionServiceorTZ instanceof TimeZoneInfo_1.TimeZoneInfo) {
                timeZone = versionServiceorTZ;
            }
            else if (versionServiceorTZ instanceof ExchangeServiceBase) {
                service = versionServiceorTZ;
            }
            else if (typeof versionServiceorTZ === 'number') {
                requestedServerVersion = versionServiceorTZ;
            }
        }
        if (argsLength === 2) {
            if (versionOrTZ instanceof TimeZoneInfo_1.TimeZoneInfo) {
                if (typeof versionServiceorTZ !== 'number') {
                    throw new Error("ExchangeServiceBase.ts - ctor with " + argsLength + " parameters - incorrect uses of parameter at 1st position, it must be ExchangeVersion when using TimeZoneInfo at 2nd place");
                }
                timeZone = versionOrTZ;
            }
            else if (typeof versionOrTZ === 'number') {
                if (!(versionServiceorTZ instanceof ExchangeServiceBase)) {
                    throw new Error("ExchangeServiceBase.ts - ctor with " + argsLength + " parameters - incorrect uses of parameter at 1st position, it must be ExchangeServiceBase when using ExchangeVersion at 2nd place");
                }
                requestedServerVersion = versionOrTZ;
            }
        }
        this.requestedServerVersion = requestedServerVersion;
        if ((0, ExtensionMethods_1.hasValue)(timeZone)) {
            this.timeZone = timeZone;
            //this.useDefaultCredentials = true; //ref: no default credential in node.js
        }
        if ((0, ExtensionMethods_1.hasValue)(service)) {
            // this.useDefaultCredentials = service.useDefaultCredentials;
            this.credentials = service.credentials;
            this.Credentials = service.Credentials;
            this.traceEnabled = service.traceEnabled;
            this.traceListener = service.traceListener;
            this.traceFlags = service.traceFlags;
            this.timeout = service.timeout;
            this.preAuthenticate = service.preAuthenticate;
            this.userAgent = service.userAgent;
            //this.acceptGzipEncoding = service.acceptGzipEncoding;
            this.keepAlive = service.keepAlive;
            this.connectionGroupName = service.connectionGroupName;
            this.timeZone = service.timeZone;
            this.httpHeaders = service.httpHeaders;
            // this.ewsHttpWebRequestFactory = service.ewsHttpWebRequestFactory;
            this.xhrApi = service.xhrApi;
        }
    }
    //#endregion
    //#region Properties
    // /** 
    //  * Gets or sets the cookie container.
    // */
    // get CookieContainer(): CookieContainer {
    //   return this.cookieContainer;
    // }
    // set CookieContainer(value: CookieContainer) {
    //   this.cookieContainer = value;
    // }
    /**
     * @internal Gets the time zone this service is scoped to.
     */
    get TimeZone() {
        return this.timeZone;
    }
    /**
     * @internal Gets a time zone definition generated from the time zone info to which this service is scoped.
     */
    get TimeZoneDefinition() {
        if (this.timeZoneDefinition === null) {
            this.timeZoneDefinition = new TimeZoneDefinition_1.TimeZoneDefinition(this.TimeZone);
        }
        return this.timeZoneDefinition;
    }
    /**
     * Gets or sets a value indicating whether client latency info is push to server.
     */
    get SendClientLatencies() {
        return this.sendClientLatencies;
    }
    set SendClientLatencies(value) {
        this.sendClientLatencies = value;
    }
    /**
     * Gets or sets a value indicating whether tracing is enabled.
     */
    get TraceEnabled() {
        return this.traceEnabled;
    }
    set TraceEnabled(value) {
        this.traceEnabled = value;
        if (this.traceEnabled && this.traceListener === null) {
            this.traceListener = new EwsTraceListener_1.EwsTraceListener();
        }
    }
    /**
     * Gets or sets the trace flags.
     */
    get TraceFlags() {
        return this.traceFlags;
    }
    set TraceFlags(value) {
        this.traceFlags = value;
    }
    /**
     * Gets or sets the trace listener.
     */
    get TraceListener() {
        return this.traceListener;
    }
    set TraceListener(value) {
        this.traceListener = value;
        this.traceEnabled = (value !== null);
    }
    /**
     * Gets or sets the credentials used to authenticate with the Exchange Web Services. Setting the Credentials property automatically sets the UseDefaultCredentials to false.
     */
    get Credentials() {
        return this.credentials;
    }
    set Credentials(value) {
        this.credentials = value;
        // this.useDefaultCredentials = false;
        // this.cookieContainer = new CookieContainer();
    }
    // /** // REF: No default credential in NodeJs
    //  * Gets or sets a value indicating whether the credentials of the user currently logged into Windows should be used to authenticate with the Exchange Web Services. Setting UseDefaultCredentials to true automatically sets the Credentials property to null.
    //  */
    // get UseDefaultCredentials(): boolean {
    //   return this.useDefaultCredentials;
    // }
    // set UseDefaultCredentials(value: boolean) {
    //   this.useDefaultCredentials = value;
    //   if (value) {
    //     this.credentials = null;
    //     // this.cookieContainer = new CookieContainer();
    //   }
    // }
    /**
     * Gets or sets the timeout used when sending HTTP requests and when receiving HTTP responses, in milliseconds. Defaults to 100000.
     */
    get Timeout() {
        return this.timeout;
    }
    set Timeout(value) {
        if (value < 1) {
            throw new ArgumentException_1.ArgumentException(Strings_1.Strings.TimeoutMustBeGreaterThanZero);
        }
        this.timeout = value;
    }
    /**
     * Gets or sets a value that indicates whether HTTP pre-authentication should be performed.
     */
    get PreAuthenticate() {
        return this.preAuthenticate;
    }
    set PreAuthenticate(value) {
        this.preAuthenticate = value;
    }
    /**
     * Gets or sets a value indicating whether GZip compression encoding should be accepted.
     * @remarks This value will tell the server that the client is able to handle GZip compression encoding. The server will only send Gzip compressed content if it has been configured to do so.
     * @remarks {ewsjs} not used in ewsjs
     */
    get AcceptGzipEncoding() {
        return this.acceptGzipEncoding;
    }
    set AcceptGzipEncoding(value) {
        this.acceptGzipEncoding = value;
    }
    /**
     * Gets the requested server version.
     */
    get RequestedServerVersion() {
        return this.requestedServerVersion;
    }
    /**
     * Gets or sets the user agent.
     */
    get UserAgent() {
        return this.userAgent;
    }
    set UserAgent(value) {
        this.userAgent = `${value} (${ExchangeServiceBase.defaultUserAgent})`;
    }
    /**
     * Gets information associated with the server that processed the last request. Will be null if no requests have been processed.
     */
    get ServerInfo() {
        return this.serverInfo;
    }
    /** @internal set */
    set ServerInfo(value) {
        this.serverInfo = value;
    }
    // /**
    //  * Gets or sets the web proxy that should be used when sending requests to EWS. Set this property to null to use the default web proxy.
    //  */
    // get WebProxy(): IWebProxy {
    //   return this.webProxy;
    // }
    // set WebProxy(value: IWebProxy) {
    //   this.webProxy = value;
    // }
    /**
     * Gets or sets if the request to the internet resource should contain a Connection HTTP header with the value Keep-alive
     */
    get KeepAlive() {
        return this.keepAlive;
    }
    set KeepAlive(value) {
        this.keepAlive = value;
    }
    /**
     * Gets or sets the name of the connection group for the request.
     */
    get ConnectionGroupName() {
        return this.connectionGroupName;
    }
    set ConnectionGroupName(value) {
        this.connectionGroupName = value;
    }
    /**
     * Gets or sets the request id for the request.
     */
    get ClientRequestId() {
        return this.clientRequestId;
    }
    set ClientRequestId(value) {
        this.clientRequestId = value;
    }
    /**
     * Gets or sets a flag to indicate whether the client requires the server side to return the  request id.
     */
    get ReturnClientRequestId() {
        return this.returnClientRequestId;
    }
    set ReturnClientRequestId(value) {
        this.returnClientRequestId = value;
    }
    /**
     * Gets a collection of HTTP headers that will be sent with each request to EWS.
     */
    get HttpHeaders() {
        return this.httpHeaders;
    }
    /**
     * Gets a collection of HTTP headers from the last response.
     */
    get HttpResponseHeaders() {
        return this.httpResponseHeaders;
    }
    /**
     * @internal Gets the session key.
     */
    static get SessionKey() {
        // TODO: fix when implement Partner tokens
        // // this has to be computed only once.
        // lock(ExchangeServiceBase.lockObj)
        // {
        //   if (ExchangeServiceBase.binarySecret === null) {
        //     RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
        //     ExchangeServiceBase.binarySecret = new byte[256 / 8];
        //     randomNumberGenerator.GetNonZeroBytes(binarySecret);
        //   }
        //   return ExchangeServiceBase.binarySecret;
        // }
        return null;
    }
    // /**
    //  * Gets or sets the HTTP web request factory.
    //  */
    // get HttpWebRequestFactory(): IEwsHttpWebRequestFactory {
    //   return this.ewsHttpWebRequestFactory;
    // }
    // set HttpWebRequestFactory(value: IEwsHttpWebRequestFactory) {
    //   this.ewsHttpWebRequestFactory = ((value === null) ? new EwsHttpWebRequestFactory() : value);
    // }
    /**
     * @internal For testing: suppresses generation of the SOAP version header.
     */
    get SuppressXmlVersionHeader() {
        return this.suppressXmlVersionHeader;
    }
    set SuppressXmlVersionHeader(value) {
        this.suppressXmlVersionHeader = value;
    }
    get XHRApi() {
        return this.xhrApi || XHRFactory_1.XHRFactory.XHRApi;
    }
    set XHRApi(xhrApi) {
        this.xhrApi = xhrApi || XHRFactory_1.XHRFactory.XHRApi;
    }
    //#endregion
    /**
     * @internal Converts the date time to universal date time string.
     *
     * @param   {DateTime}  value   The value.
     * @return  {string}    String representation of DateTime.
     */
    ConvertDateTimeToUniversalDateTimeString(value) {
        var dateTime;
        switch (value.Kind) {
            case DateTime_1.DateTimeKind.Unspecified:
                dateTime = EwsUtilities_1.EwsUtilities.ConvertTime(value, this.TimeZone, TimeZoneInfo_1.TimeZoneInfo.Utc);
                break;
            case DateTime_1.DateTimeKind.Local:
                dateTime = EwsUtilities_1.EwsUtilities.ConvertTime(value, TimeZoneInfo_1.TimeZoneInfo.Local, TimeZoneInfo_1.TimeZoneInfo.Utc);
                break;
            default:
                // The date is already in UTC, no need to convert it.
                dateTime = value;
                break;
        }
        //debug://todo:iso string should work
        return dateTime.ToISOString(); // ISO string should work .ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture);
    }
    /**
     * @internal Converts xs:dateTime string with either "Z", "-00:00" bias, or "" suffixes to unspecified StartDate value ignoring the suffix.
    *
    * @param   {string}   value   The string value to parse.
    * @return  {DateTime} The parsed DateTime value.
    */
    ConvertStartDateToUnspecifiedDateTime(value) {
        //EwsLogging.Log("ExchangeServiceBase.ConvConvertStartDateToUnspecifiedDateTime : DateTimeOffset not implemented, check date values")
        value = value.substring(0, 10); //info: //ref: for DateTimeOffset substitution, this is being called only from recurring datetime StartDate and 
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(value)) {
            return null;
        }
        else {
            return DateTime_1.DateTime.Parse(value);
            //let dateTimeOffset:DateTimeOffset = DateTimeOffset.Parse(value, CultureInfo.InvariantCulture);
            // Return only the date part with the kind==Unspecified.
            //return dateTimeOffset.Date;
        }
    }
    /**
     * @internal Converts the universal date time string to local date time.
     *
     * @param   {string}    value   The value.
     * @return  {DateTime}  DateTime
     */
    ConvertUniversalDateTimeStringToLocalDateTime(value) {
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(value)) {
            return null;
        }
        else {
            // Assume an unbiased date/time is in UTC. Convert to UTC otherwise.
            //ref: //fix: hard convert to UTC date as no request contains TZ information.
            if (value.toLowerCase().indexOf("z") < 0 && ["+", "-"].indexOf(value.substr(19, 1)) < 0) {
                value += "Z";
            }
            var dateTime = DateTime_1.DateTime.Parse(value);
            // CultureInfo.InvariantCulture,
            // DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
            if (this.TimeZone === TimeZoneInfo_1.TimeZoneInfo.Utc) {
                // This returns a DateTime with Kind.Utc
                return dateTime;
            }
            else {
                var localTime = EwsUtilities_1.EwsUtilities.ConvertTime(dateTime, TimeZoneInfo_1.TimeZoneInfo.Utc, this.TimeZone);
                if (EwsUtilities_1.EwsUtilities.IsLocalTimeZone(this.TimeZone)) {
                    // This returns a DateTime with Kind.Local
                    return new DateTime_1.DateTime(localTime.TotalMilliSeconds, DateTime_1.DateTimeKind.Local);
                }
                else {
                    // This returns a DateTime with Kind.Unspecified
                    return localTime;
                }
            }
        }
    }
    /**
     * @internal Calls the custom SOAP header serialization event handlers, if defined.
     *
     * @param   {EwsServiceXmlWriter}   writer   The XmlWriter to which to write the custom SOAP headers.
     */
    DoOnSerializeCustomSoapHeaders(writer) {
        EwsLogging_1.EwsLogging.Assert(writer != null, "ExchangeServiceBase.DoOnSerializeCustomSoapHeaders", "writer is null");
        if (this.OnSerializeCustomSoapHeaders != null) {
            this.OnSerializeCustomSoapHeaders(writer);
        }
    }
    /**
     * @internal Processes an HTTP error response
     *
     * /remarks/    This method doesn't handle 500 ISE errors. This is handled by the caller since 500 ISE typically indicates that a SOAP fault has occurred and the handling of a SOAP fault is currently service specific.
     * @param   {XMLHttpRequest}    httpWebResponse            The HTTP web response.
     * @param   {SoapFaultDetails}  webException               The web exception.
     * @param   {TraceFlags}        responseHeadersTraceFlag   The trace flag for response headers.
     * @param   {TraceFlags}        responseTraceFlag          The trace flag for responses.
     *
     */
    InternalProcessHttpErrorResponse(httpWebResponse, soapFault, responseHeadersTraceFlag, responseTraceFlag) {
        EwsLogging_1.EwsLogging.Assert(httpWebResponse.status != 500, // HttpStatusCode.InternalServerError,
        "ExchangeServiceBase.InternalProcessHttpErrorResponse", "InternalProcessHttpErrorResponse does not handle 500 ISE errors, the caller is supposed to handle this.");
        this.ProcessHttpResponseHeaders(responseHeadersTraceFlag, httpWebResponse);
        let exception = null;
        // Deal with new HTTP error code indicating that account is locked.
        // The "unlock" URL is returned as the status description in the response.
        if (httpWebResponse.status === ExchangeServiceBase.AccountIsLocked) {
            EwsLogging_1.EwsLogging.Assert(false, "ExchangeServiceBase.InternalProcessHttpErrorResponse", "Please report back to ews-javascript-api with example or response XML for future improvements of this code.");
            let location = httpWebResponse.getResponseHeader("StatusDescription");
            let accountUnlockUrl = null;
            //if (Uri.IsWellFormedUriString(location, UriKind.Absolute)) {
            if (Uri_1.Uri.ParseString(location).authority) { //todo: implement better Url parsing in Uri.
                accountUnlockUrl = new Uri_1.Uri(location);
            }
            this.TraceMessage(responseTraceFlag, ExtensionMethods_1.StringHelper.Format("Account is locked. Unlock URL is {0}", accountUnlockUrl.ToString()));
            exception = new AccountIsLockedException_1.AccountIsLockedException(ExtensionMethods_1.StringHelper.Format(Strings_1.Strings.AccountIsLocked, accountUnlockUrl), accountUnlockUrl, null);
        }
        else if (httpWebResponse.status === 401 /*Unauthorized*/) {
            exception = new ServiceRequestUnauthorizedException_1.ServiceRequestUnauthorizedException("401 Unauthorized");
        }
        if (exception) {
            if (soapFault !== null) {
                soapFault.Exception = exception;
                if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(soapFault.message) && !ExtensionMethods_1.StringHelper.IsNullOrEmpty(exception.message)) {
                    soapFault.message = exception.message;
                }
            }
            else {
                throw exception;
            }
        }
    }
    /**
     * @internal Determines whether tracing is enabled for specified trace flag(s).
     *
     * @param   {TraceFlags}  traceFlags   The trace flags.
     * @return  {boolean}     True if tracing is enabled for specified trace flag(s).
     */
    IsTraceEnabledFor(traceFlags) {
        return this.TraceEnabled && ((this.TraceFlags & traceFlags) != 0);
    }
    /**
    * @internal Creates an HttpWebRequest instance and initializes it with the appropriate parameters, based on the configuration of this service object.
    *
    * @param   {Uri}          url                  The URL that the HttpWebRequest should target.
    * @param   {boolean}      acceptGzipEncoding   If true, ask server for GZip compressed content.
    * @param   {boolean}      allowAutoRedirect    If true, redirection responses will be automatically followed.
    * @return  {IXHROptions}  A initialized instance of IXHROptions.
    */
    PrepareHttpWebRequestForUrl(url, acceptGzipEncoding, allowAutoRedirect) {
        // Verify that the protocol is something that we can handle
        if ((url.Scheme != Uri_1.Uri.UriSchemeHttp) && (url.Scheme != Uri_1.Uri.UriSchemeHttps)) {
            throw new ServiceLocalException_1.ServiceLocalException("unsupported web protocol" + url); //string.Format(Strings.UnsupportedWebProtocol, url.Scheme));
        }
        var request = { url: url.ToString() };
        request.headers = {};
        //request.PreAuthenticate = this.PreAuthenticate;
        //request.Timeout = this.Timeout; //todo: implement this within IPromise
        this.SetContentType(request);
        request.type = "POST";
        //request.headers["User-Agent"] = this.UserAgent || ExchangeServiceBase.defaultUserAgent; //todo:fix -> Noje.js is refusing to set this unsafe header -//
        //request.AllowAutoRedirect = allowAutoRedirect;
        //todo: figure out next 3 lines
        //request.CookieContainer = this.CookieContainer;
        //request.KeepAlive = this.keepAlive;
        //request.ConnectionGroupName = this.connectionGroupName;
        if (acceptGzipEncoding) {
            request.headers["Accept-Encoding"] = "gzip,deflate";
        }
        if (!ExtensionMethods_1.StringHelper.IsNullOrEmpty(this.clientRequestId)) {
            request.headers["client-request-id"] = this.clientRequestId;
            if (this.returnClientRequestId) {
                request.headers["return-client-request-id"] = "true";
            }
        }
        //if (this.webProxy != null) {
        //    request.Proxy = this.webProxy;
        //}
        if (this.HttpHeaders) {
            for (var key of this.HttpHeaders.Keys) {
                request.headers[key] = this.HttpHeaders.get(key);
            }
        }
        // REF: no default credential in NodeJs
        // request.UseDefaultCredentials = this.UseDefaultCredentials;
        // if (!this.UseDefaultCredentials) {
        var serviceCredentials = this.Credentials;
        if (serviceCredentials === null) {
            throw new ServiceLocalException_1.ServiceLocalException(Strings_1.Strings.CredentialsRequired);
        }
        // Make sure that credentials have been authenticated if required
        //serviceCredentials.PreAuthenticate(); //todo: fix preauthenticate if possible
        // Apply credentials to the request
        serviceCredentials.PrepareWebRequest(request);
        // }
        // else
        //     debugger;
        this.httpResponseHeaders.clear();
        return request;
    }
    /**
     * @internal Traces the HTTP response headers.
     *
     * @param   {TraceFlags}   traceType   Kind of trace entry.
     * @param   {XMLHttpRequest}   response    The response.
     */
    ProcessHttpResponseHeaders(traceType, response) {
        //TODO: implement tracing properly
        this.TraceHttpResponseHeaders(traceType, response);
        this.SaveHttpResponseHeaders(response);
    }
    /**
     * Save the HTTP response headers.
     *
     * @param   {Object}   response   The response headers
     */
    SaveHttpResponseHeaders(response /* System.Net.WebHeaderCollection*/) {
        //debug:
        this.httpResponseHeaders.clear();
        for (var key in response.headers || {}) {
            this.httpResponseHeaders.Add(key, response.headers[key]);
        }
        if (this.OnResponseHeadersCaptured != null) {
            this.OnResponseHeadersCaptured(this.httpResponseHeaders);
        }
    }
    /**
     * @internal
     * @virtual
     */
    SetContentType(request /*IEwsHttpWebRequest*/) {
        request.headers["Content-Type"] = "text/xml; charset=utf-8";
        request.headers["Accept"] = "text/xml";
    }
    /**
     * @internal Sets the user agent to a custom value
     *
     * @param   {string}   userAgent   User agent string to set on the service
     */
    SetCustomUserAgent(userAgent) {
        this.userAgent = userAgent;
    }
    /**
     * @internal Traces the HTTP request headers.
     *
     * @param   {TraceFlags}  traceType   Kind of trace entry.
     * @param   {IXHROptions} request     The request.
     */
    TraceHttpRequestHeaders(traceType, request) {
        if (this.IsTraceEnabledFor(traceType)) {
            const traceTypeStr = TraceFlags_1.TraceFlags[traceType];
            const headersAsString = EwsUtilities_1.EwsUtilities.FormatHttpRequestHeaders(request.headers);
            const logMessage = EwsUtilities_1.EwsUtilities.FormatLogMessage(traceTypeStr, headersAsString);
            this.TraceListener.Trace(traceTypeStr, logMessage);
        }
    }
    /**
     * Traces the HTTP response headers.
     *
     * @param   {TraceFlags}   traceType   Kind of trace entry.
     * @param   {XMLHttpRequest}   response    The response.
     */
    TraceHttpResponseHeaders(traceType, response) {
        if (this.IsTraceEnabledFor(traceType)) {
            const traceTypeStr = TraceFlags_1.TraceFlags[traceType];
            const headersAsString = EwsUtilities_1.EwsUtilities.FormatHttpResponseHeaders(response);
            const logMessage = EwsUtilities_1.EwsUtilities.FormatLogMessage(traceTypeStr, headersAsString);
            this.TraceListener.Trace(traceTypeStr, logMessage);
        }
    }
    /**
     * @internal Logs the specified string to the TraceListener if tracing is enabled.
     *
     * @param   {TraceFlags}  traceType   Kind of trace entry.
     * @param   {string}      logEntry    The entry to log.
     */
    TraceMessage(traceType, logEntry) { EwsLogging_1.EwsLogging.Log(logEntry); /*throw new Error("Not implemented."); */ }
    /**
     * @internal Logs the specified XML to the TraceListener if tracing is enabled.
     *
     * @param   {TraceFlags}  traceType   Kind of trace entry.
     * @param   {XMLHttpRequest}         stream      The XMLHttpRequest containing XML.
     */
    TraceXml(traceType, stream) {
        if (this.IsTraceEnabledFor(traceType)) {
            const traceTypeStr = TraceFlags_1.TraceFlags[traceType];
            const logMessage = EwsUtilities_1.EwsUtilities.FormatLogMessageWithXmlContent(traceTypeStr, stream);
            this.TraceListener.Trace(traceTypeStr, logMessage);
        }
    }
    /**
     * @internal Validates this instance.
     * @virtual
     */
    Validate() { }
}
exports.ExchangeServiceBase = ExchangeServiceBase;
/**
 * @internal Special HTTP status code that indicates that the account is locked.
 */
ExchangeServiceBase.AccountIsLocked = 456 /* Autodiscover_ContactAdmin */;
/**
 * The binary secret.
 */
ExchangeServiceBase.binarySecret = null;
//#endregion
//#region static members
/**
 * Default UserAgent
 */
ExchangeServiceBase.defaultUserAgent = `ExchangeServicesClient/${EwsUtilities_1.EwsUtilities.BuildVersion}`;
//# sourceMappingURL=ExchangeServiceBase.js.map