/*
 * Application Insights JavaScript SDK - Channel, 3.3.10
 * Copyright (c) Microsoft and contributors. All rights reserved.
 */
import { __assignFn as __assign } from "@microsoft/applicationinsights-shims";
import { CtxTagKeys, Data, Envelope, Event, Exception, HttpMethod, Metric, PageView, PageViewPerformance, RemoteDependencyData, SampleRate, Trace, dataSanitizeString } from "@microsoft/applicationinsights-common";
import { _throwInternal, _warnToConsole, getJSON, hasJSON, isNullOrUndefined, isNumber, isString, isTruthy, objForEachKey, optimizeObject, setValue, toISOString } from "@microsoft/applicationinsights-core-js";
import { STR_DURATION } from "./InternalConstants";
import { _DYN_DATA, _DYN_DATA_TYPE, _DYN_DEVICE_TYPE, _DYN_ENVELOPE_TYPE, _DYN_LENGTH, _DYN_MEASUREMENTS, _DYN_NAME, _DYN_STRINGIFY, _DYN_TAGS, _DYN_TO_STRING, _DYN_TRACE_ID } from "./__DynamicConstants";
// these two constants are used to filter out properties not needed when trying to extract custom properties and measurements from the incoming payload
var strBaseType = "baseType";
var strBaseData = "baseData";
var strProperties = "properties";
var strTrue = "true";
function _setValueIf(target, field, value) {
    return setValue(target, field, value, isTruthy);
}
/*
 * Maps Part A data from CS 4.0
 */
function _extractPartAExtensions(logger, item, env) {
    // todo: switch to keys from common in this method
    var envTags = env[_DYN_TAGS /* @min:%2etags */] = env[_DYN_TAGS /* @min:%2etags */] || {};
    var itmExt = item.ext = item.ext || {};
    var itmTags = item[_DYN_TAGS /* @min:%2etags */] = item[_DYN_TAGS /* @min:%2etags */] || [];
    var extUser = itmExt.user;
    if (extUser) {
        _setValueIf(envTags, CtxTagKeys.userAuthUserId, extUser.authId);
        _setValueIf(envTags, CtxTagKeys.userId, extUser.id || extUser.localId);
    }
    var extApp = itmExt.app;
    if (extApp) {
        _setValueIf(envTags, CtxTagKeys.sessionId, extApp.sesId);
    }
    var extDevice = itmExt.device;
    if (extDevice) {
        _setValueIf(envTags, CtxTagKeys.deviceId, extDevice.id || extDevice.localId);
        _setValueIf(envTags, CtxTagKeys[_DYN_DEVICE_TYPE /* @min:%2edeviceType */], extDevice.deviceClass);
        _setValueIf(envTags, CtxTagKeys.deviceIp, extDevice.ip);
        _setValueIf(envTags, CtxTagKeys.deviceModel, extDevice.model);
        _setValueIf(envTags, CtxTagKeys[_DYN_DEVICE_TYPE /* @min:%2edeviceType */], extDevice[_DYN_DEVICE_TYPE /* @min:%2edeviceType */]);
    }
    var web = item.ext.web;
    if (web) {
        _setValueIf(envTags, CtxTagKeys.deviceLanguage, web.browserLang);
        _setValueIf(envTags, CtxTagKeys.deviceBrowserVersion, web.browserVer);
        _setValueIf(envTags, CtxTagKeys.deviceBrowser, web.browser);
        var envData = env[_DYN_DATA /* @min:%2edata */] = env[_DYN_DATA /* @min:%2edata */] || {};
        var envBaseData = envData[strBaseData] = envData[strBaseData] || {};
        var envProps = envBaseData[strProperties] = envBaseData[strProperties] || {};
        _setValueIf(envProps, "domain", web.domain);
        _setValueIf(envProps, "isManual", web.isManual ? strTrue : null);
        _setValueIf(envProps, "screenRes", web.screenRes);
        _setValueIf(envProps, "userConsent", web.userConsent ? strTrue : null);
    }
    var extOs = itmExt.os;
    if (extOs) {
        _setValueIf(envTags, CtxTagKeys.deviceOS, extOs[_DYN_NAME /* @min:%2ename */]);
        _setValueIf(envTags, CtxTagKeys.deviceOSVersion, extOs.osVer);
    }
    // No support for mapping Trace.traceState to 2.0 as it is currently empty
    var extTrace = itmExt.trace;
    if (extTrace) {
        _setValueIf(envTags, CtxTagKeys.operationParentId, extTrace.parentID);
        _setValueIf(envTags, CtxTagKeys.operationName, dataSanitizeString(logger, extTrace[_DYN_NAME /* @min:%2ename */]));
        _setValueIf(envTags, CtxTagKeys.operationId, extTrace[_DYN_TRACE_ID /* @min:%2etraceID */]);
    }
    // Sample 4.0 schema
    //  {
    //     "time" : "2018-09-05T22:51:22.4936Z",
    //     "name" : "MetricWithNamespace",
    //     "iKey" : "ABC-5a4cbd20-e601-4ef5-a3c6-5d6577e4398e",
    //     "ext": {  "cloud": {
    //          "role": "WATSON3",
    //          "roleInstance": "CO4AEAP00000260"
    //      },
    //      "device": {}, "correlation": {} },
    //      "tags": [
    //        { "amazon.region" : "east2" },
    //        { "os.expid" : "wp:02df239" }
    //     ]
    //   }
    var tgs = {};
    // deals with tags.push({object})
    for (var i = itmTags[_DYN_LENGTH /* @min:%2elength */] - 1; i >= 0; i--) {
        var tg = itmTags[i];
        objForEachKey(tg, function (key, value) {
            tgs[key] = value;
        });
        itmTags.splice(i, 1);
    }
    // deals with tags[key]=value (and handles hasOwnProperty)
    objForEachKey(itmTags, function (tg, value) {
        tgs[tg] = value;
    });
    var theTags = __assign(__assign({}, envTags), tgs);
    if (!theTags[CtxTagKeys.internalSdkVersion]) {
        // Append a version in case it is not already set
        theTags[CtxTagKeys.internalSdkVersion] = dataSanitizeString(logger, "javascript:".concat(EnvelopeCreator.Version), 64);
    }
    env[_DYN_TAGS /* @min:%2etags */] = optimizeObject(theTags);
}
function _extractPropsAndMeasurements(data, properties, measurements) {
    if (!isNullOrUndefined(data)) {
        objForEachKey(data, function (key, value) {
            if (isNumber(value)) {
                measurements[key] = value;
            }
            else if (isString(value)) {
                properties[key] = value;
            }
            else if (hasJSON()) {
                properties[key] = getJSON()[_DYN_STRINGIFY /* @min:%2estringify */](value);
            }
        });
    }
}
function _convertPropsUndefinedToCustomDefinedValue(properties, customUndefinedValue) {
    if (!isNullOrUndefined(properties)) {
        objForEachKey(properties, function (key, value) {
            properties[key] = value || customUndefinedValue;
        });
    }
}
// TODO: Do we want this to take logger as arg or use this._logger as nonstatic?
function _createEnvelope(logger, envelopeType, telemetryItem, data) {
    var envelope = new Envelope(logger, data, envelopeType);
    _setValueIf(envelope, "sampleRate", telemetryItem[SampleRate]);
    if ((telemetryItem[strBaseData] || {}).startTime) {
        // Starting from Version 3.0.3, the time property will be assigned by the startTime value,
        // which records the loadEvent time for the pageView event.
        envelope.time = toISOString(telemetryItem[strBaseData].startTime);
    }
    envelope.iKey = telemetryItem.iKey;
    var iKeyNoDashes = telemetryItem.iKey.replace(/-/g, "");
    envelope[_DYN_NAME /* @min:%2ename */] = envelope[_DYN_NAME /* @min:%2ename */].replace("{0}", iKeyNoDashes);
    // extract all extensions from ctx
    _extractPartAExtensions(logger, telemetryItem, envelope);
    // loop through the envelope tags (extension of Part A) and pick out the ones that should go in outgoing envelope tags
    telemetryItem[_DYN_TAGS /* @min:%2etags */] = telemetryItem[_DYN_TAGS /* @min:%2etags */] || [];
    return optimizeObject(envelope);
}
function EnvelopeCreatorInit(logger, telemetryItem) {
    if (isNullOrUndefined(telemetryItem[strBaseData])) {
        _throwInternal(logger, 1 /* eLoggingSeverity.CRITICAL */, 46 /* _eInternalMessageId.TelemetryEnvelopeInvalid */, "telemetryItem.baseData cannot be null.");
    }
}
export var EnvelopeCreator = {
    Version: '3.3.10'
};
export function DependencyEnvelopeCreator(logger, telemetryItem, customUndefinedValue) {
    EnvelopeCreatorInit(logger, telemetryItem);
    var customMeasurements = telemetryItem[strBaseData][_DYN_MEASUREMENTS /* @min:%2emeasurements */] || {};
    var customProperties = telemetryItem[strBaseData][strProperties] || {};
    _extractPropsAndMeasurements(telemetryItem[_DYN_DATA /* @min:%2edata */], customProperties, customMeasurements);
    if (!isNullOrUndefined(customUndefinedValue)) {
        _convertPropsUndefinedToCustomDefinedValue(customProperties, customUndefinedValue);
    }
    var bd = telemetryItem[strBaseData];
    if (isNullOrUndefined(bd)) {
        _warnToConsole(logger, "Invalid input for dependency data");
        return null;
    }
    var method = bd[strProperties] && bd[strProperties][HttpMethod] ? bd[strProperties][HttpMethod] : "GET";
    var remoteDepData = new RemoteDependencyData(logger, bd.id, bd.target, bd[_DYN_NAME /* @min:%2ename */], bd[STR_DURATION /* @min:%2eduration */], bd.success, bd.responseCode, method, bd.type, bd.correlationContext, customProperties, customMeasurements);
    var data = new Data(RemoteDependencyData[_DYN_DATA_TYPE /* @min:%2edataType */], remoteDepData);
    return _createEnvelope(logger, RemoteDependencyData[_DYN_ENVELOPE_TYPE /* @min:%2eenvelopeType */], telemetryItem, data);
}
export function EventEnvelopeCreator(logger, telemetryItem, customUndefinedValue) {
    EnvelopeCreatorInit(logger, telemetryItem);
    var customProperties = {};
    var customMeasurements = {};
    if (telemetryItem[strBaseType] !== Event[_DYN_DATA_TYPE /* @min:%2edataType */]) {
        customProperties["baseTypeSource"] = telemetryItem[strBaseType]; // save the passed in base type as a property
    }
    if (telemetryItem[strBaseType] === Event[_DYN_DATA_TYPE /* @min:%2edataType */]) { // take collection
        customProperties = telemetryItem[strBaseData][strProperties] || {};
        customMeasurements = telemetryItem[strBaseData][_DYN_MEASUREMENTS /* @min:%2emeasurements */] || {};
    }
    else { // if its not a known type, convert to custom event
        if (telemetryItem[strBaseData]) {
            _extractPropsAndMeasurements(telemetryItem[strBaseData], customProperties, customMeasurements);
        }
    }
    // Extract root level properties from part C telemetryItem.data
    _extractPropsAndMeasurements(telemetryItem[_DYN_DATA /* @min:%2edata */], customProperties, customMeasurements);
    if (!isNullOrUndefined(customUndefinedValue)) {
        _convertPropsUndefinedToCustomDefinedValue(customProperties, customUndefinedValue);
    }
    var eventName = telemetryItem[strBaseData][_DYN_NAME /* @min:%2ename */];
    var eventData = new Event(logger, eventName, customProperties, customMeasurements);
    var data = new Data(Event[_DYN_DATA_TYPE /* @min:%2edataType */], eventData);
    return _createEnvelope(logger, Event[_DYN_ENVELOPE_TYPE /* @min:%2eenvelopeType */], telemetryItem, data);
}
export function ExceptionEnvelopeCreator(logger, telemetryItem, customUndefinedValue) {
    EnvelopeCreatorInit(logger, telemetryItem);
    // Extract root level properties from part C telemetryItem.data
    var customMeasurements = telemetryItem[strBaseData][_DYN_MEASUREMENTS /* @min:%2emeasurements */] || {};
    var customProperties = telemetryItem[strBaseData][strProperties] || {};
    _extractPropsAndMeasurements(telemetryItem[_DYN_DATA /* @min:%2edata */], customProperties, customMeasurements);
    if (!isNullOrUndefined(customUndefinedValue)) {
        _convertPropsUndefinedToCustomDefinedValue(customProperties, customUndefinedValue);
    }
    var bd = telemetryItem[strBaseData];
    var exData = Exception.CreateFromInterface(logger, bd, customProperties, customMeasurements);
    var data = new Data(Exception[_DYN_DATA_TYPE /* @min:%2edataType */], exData);
    return _createEnvelope(logger, Exception[_DYN_ENVELOPE_TYPE /* @min:%2eenvelopeType */], telemetryItem, data);
}
export function MetricEnvelopeCreator(logger, telemetryItem, customUndefinedValue) {
    EnvelopeCreatorInit(logger, telemetryItem);
    var baseData = telemetryItem[strBaseData];
    var props = baseData[strProperties] || {};
    var measurements = baseData[_DYN_MEASUREMENTS /* @min:%2emeasurements */] || {};
    _extractPropsAndMeasurements(telemetryItem[_DYN_DATA /* @min:%2edata */], props, measurements);
    if (!isNullOrUndefined(customUndefinedValue)) {
        _convertPropsUndefinedToCustomDefinedValue(props, customUndefinedValue);
    }
    var baseMetricData = new Metric(logger, baseData[_DYN_NAME /* @min:%2ename */], baseData.average, baseData.sampleCount, baseData.min, baseData.max, baseData.stdDev, props, measurements);
    var data = new Data(Metric[_DYN_DATA_TYPE /* @min:%2edataType */], baseMetricData);
    return _createEnvelope(logger, Metric[_DYN_ENVELOPE_TYPE /* @min:%2eenvelopeType */], telemetryItem, data);
}
export function PageViewEnvelopeCreator(logger, telemetryItem, customUndefinedValue) {
    EnvelopeCreatorInit(logger, telemetryItem);
    // Since duration is not part of the domain properties in Common Schema, extract it from part C
    var duration;
    var baseData = telemetryItem[strBaseData];
    if (!isNullOrUndefined(baseData) &&
        !isNullOrUndefined(baseData[strProperties]) &&
        !isNullOrUndefined(baseData[strProperties][STR_DURATION])) { // from part B properties
        duration = baseData[strProperties][STR_DURATION];
        delete baseData[strProperties][STR_DURATION];
    }
    else if (!isNullOrUndefined(telemetryItem[_DYN_DATA /* @min:%2edata */]) &&
        !isNullOrUndefined(telemetryItem[_DYN_DATA /* @min:%2edata */][STR_DURATION])) { // from custom properties
        duration = telemetryItem[_DYN_DATA /* @min:%2edata */][STR_DURATION];
        delete telemetryItem[_DYN_DATA /* @min:%2edata */][STR_DURATION];
    }
    var bd = telemetryItem[strBaseData];
    // special case: pageview.id is grabbed from current operation id. Analytics plugin is decoupled from properties plugin, so this is done here instead. This can be made a default telemetry intializer instead if needed to be decoupled from channel
    var currentContextId;
    if (((telemetryItem.ext || {}).trace || {})[_DYN_TRACE_ID /* @min:%2etraceID */]) {
        currentContextId = telemetryItem.ext.trace[_DYN_TRACE_ID /* @min:%2etraceID */];
    }
    var id = bd.id || currentContextId;
    var name = bd[_DYN_NAME /* @min:%2ename */];
    var url = bd.uri;
    var properties = bd[strProperties] || {};
    var measurements = bd[_DYN_MEASUREMENTS /* @min:%2emeasurements */] || {};
    // refUri is a field that Breeze still does not recognize as part of Part B. For now, put it in Part C until it supports it as a domain property
    if (!isNullOrUndefined(bd.refUri)) {
        properties["refUri"] = bd.refUri;
    }
    // pageType is a field that Breeze still does not recognize as part of Part B. For now, put it in Part C until it supports it as a domain property
    if (!isNullOrUndefined(bd.pageType)) {
        properties["pageType"] = bd.pageType;
    }
    // isLoggedIn is a field that Breeze still does not recognize as part of Part B. For now, put it in Part C until it supports it as a domain property
    if (!isNullOrUndefined(bd.isLoggedIn)) {
        properties["isLoggedIn"] = bd.isLoggedIn[_DYN_TO_STRING /* @min:%2etoString */]();
    }
    // pageTags is a field that Breeze still does not recognize as part of Part B. For now, put it in Part C until it supports it as a domain property
    if (!isNullOrUndefined(bd[strProperties])) {
        var pageTags = bd[strProperties];
        objForEachKey(pageTags, function (key, value) {
            properties[key] = value;
        });
    }
    _extractPropsAndMeasurements(telemetryItem[_DYN_DATA /* @min:%2edata */], properties, measurements);
    if (!isNullOrUndefined(customUndefinedValue)) {
        _convertPropsUndefinedToCustomDefinedValue(properties, customUndefinedValue);
    }
    var pageViewData = new PageView(logger, name, url, duration, properties, measurements, id);
    var data = new Data(PageView[_DYN_DATA_TYPE /* @min:%2edataType */], pageViewData);
    return _createEnvelope(logger, PageView[_DYN_ENVELOPE_TYPE /* @min:%2eenvelopeType */], telemetryItem, data);
}
export function PageViewPerformanceEnvelopeCreator(logger, telemetryItem, customUndefinedValue) {
    EnvelopeCreatorInit(logger, telemetryItem);
    var bd = telemetryItem[strBaseData];
    var name = bd[_DYN_NAME /* @min:%2ename */];
    var url = bd.uri || bd.url;
    var properties = bd[strProperties] || {};
    var measurements = bd[_DYN_MEASUREMENTS /* @min:%2emeasurements */] || {};
    _extractPropsAndMeasurements(telemetryItem[_DYN_DATA /* @min:%2edata */], properties, measurements);
    if (!isNullOrUndefined(customUndefinedValue)) {
        _convertPropsUndefinedToCustomDefinedValue(properties, customUndefinedValue);
    }
    var baseData = new PageViewPerformance(logger, name, url, undefined, properties, measurements, bd);
    var data = new Data(PageViewPerformance[_DYN_DATA_TYPE /* @min:%2edataType */], baseData);
    return _createEnvelope(logger, PageViewPerformance[_DYN_ENVELOPE_TYPE /* @min:%2eenvelopeType */], telemetryItem, data);
}
export function TraceEnvelopeCreator(logger, telemetryItem, customUndefinedValue) {
    EnvelopeCreatorInit(logger, telemetryItem);
    var message = telemetryItem[strBaseData].message;
    var severityLevel = telemetryItem[strBaseData].severityLevel;
    var props = telemetryItem[strBaseData][strProperties] || {};
    var measurements = telemetryItem[strBaseData][_DYN_MEASUREMENTS /* @min:%2emeasurements */] || {};
    _extractPropsAndMeasurements(telemetryItem[_DYN_DATA /* @min:%2edata */], props, measurements);
    if (!isNullOrUndefined(customUndefinedValue)) {
        _convertPropsUndefinedToCustomDefinedValue(props, customUndefinedValue);
    }
    var baseData = new Trace(logger, message, severityLevel, props, measurements);
    var data = new Data(Trace[_DYN_DATA_TYPE /* @min:%2edataType */], baseData);
    return _createEnvelope(logger, Trace[_DYN_ENVELOPE_TYPE /* @min:%2eenvelopeType */], telemetryItem, data);
}
//# sourceMappingURL=EnvelopeCreator.js.map