"use strict";
/*---------------------------------------------------------
 * Copyright (C) Microsoft Corporation. All rights reserved.
 *--------------------------------------------------------*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TelemetryReporter = void 0;
const https = __importStar(require("https"));
const os = __importStar(require("os"));
const vscode = __importStar(require("vscode"));
const _1dsClientFactory_1 = require("../common/1dsClientFactory");
const appInsightsClientFactory_1 = require("../common/appInsightsClientFactory");
const baseTelemetryReporter_1 = require("../common/baseTelemetryReporter");
const baseTelemetrySender_1 = require("../common/baseTelemetrySender");
const util_1 = require("../common/util");
/**
 * Create a replacement for the XHTMLRequest object utilizing nodes HTTP module.
 * @returns A XHR override object used to override the XHTMLRequest object in the 1DS SDK
 */
function getDefaultXHROverride() {
    // Override the way events get sent since node doesn't have XHTMLRequest
    const customHttpXHROverride = {
        sendPOST: (payload, oncomplete) => {
            const options = {
                method: "POST",
                headers: {
                    ...payload.headers,
                    "Content-Type": "application/json",
                    "Content-Length": Buffer.byteLength(payload.data)
                }
            };
            try {
                const req = https.request(payload.urlString, options, res => {
                    res.on("data", function (responseData) {
                        oncomplete(res.statusCode ?? 200, res.headers, responseData.toString());
                    });
                    // On response with error send status of 0 and a blank response to oncomplete so we can retry events
                    res.on("error", function () {
                        oncomplete(0, {});
                    });
                });
                req.write(payload.data, (err) => {
                    if (err) {
                        oncomplete(0, {});
                    }
                });
                req.end();
            }
            catch {
                // If it errors out, send status of 0 and a blank response to oncomplete so we can retry events
                oncomplete(0, {});
            }
        }
    };
    return customHttpXHROverride;
}
/**
 * Create an XHR override from a custom fetcher function.
 * @param fetcher The custom fetcher function to use for sending telemetry data
 * @returns A XHR override object used to override the XHTMLRequest object in the 1DS SDK
 */
function createXHROverrideFromFetcher(fetcher) {
    const xhrOverride = {
        sendPOST: (payload, oncomplete) => {
            const dataString = typeof payload.data === "string" ? payload.data : Buffer.from(payload.data).toString();
            const headers = { ...payload.headers };
            // if the content-type header isn't already set, default it to application/json
            if (!Object.keys(headers).some(k => k.toLowerCase() === "content-type")) {
                headers["Content-Type"] = "application/json";
            }
            fetcher(payload.urlString, { method: "POST", headers, body: dataString })
                .then(async (response) => {
                const responseHeaders = {};
                for (const [key, value] of response.headers) {
                    responseHeaders[key] = value;
                }
                const body = await response.text();
                oncomplete(response.status, responseHeaders, body);
            })
                .catch(() => {
                // If it errors out, send status of 0 and a blank response to oncomplete so we can retry events
                oncomplete(0, {});
            });
        }
    };
    return xhrOverride;
}
class TelemetryReporter extends baseTelemetryReporter_1.BaseTelemetryReporter {
    constructor(connectionString, replacementOptions, initializationOptions, customFetcher, appInsightsOptions) {
        const xhrOverride = customFetcher ? createXHROverrideFromFetcher(customFetcher) : getDefaultXHROverride();
        let clientFactory = (connectionString) => (0, appInsightsClientFactory_1.appInsightsClientFactory)(connectionString, vscode.env.machineId, vscode.env.sessionId, xhrOverride, replacementOptions, appInsightsOptions);
        // If connection string is usable by 1DS use the 1DS SDk
        if (util_1.TelemetryUtil.shouldUseOneDataSystemSDK(connectionString)) {
            clientFactory = (key) => (0, _1dsClientFactory_1.oneDataSystemClientFactory)(key, vscode, xhrOverride);
        }
        const osShim = {
            release: os.release(),
            platform: os.platform(),
            architecture: os.arch(),
        };
        const sender = new baseTelemetrySender_1.BaseTelemetrySender(connectionString, clientFactory);
        if (connectionString && connectionString.indexOf("AIF-") === 0) {
            throw new Error("AIF keys are no longer supported. Please switch to 1DS keys for 1st party extensions");
        }
        const initializationOpts = {
            ...initializationOptions,
            additionalCommonProperties: initializationOptions?.additionalCommonProperties ?
                { ...initializationOptions.additionalCommonProperties, ...util_1.TelemetryUtil.getAdditionalCommonProperties(osShim) }
                : util_1.TelemetryUtil.getAdditionalCommonProperties(osShim)
        };
        super(sender, vscode, initializationOpts);
    }
}
exports.TelemetryReporter = TelemetryReporter;
//# sourceMappingURL=telemetryReporter.js.map