"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
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.TelemetryConfig = void 0;
const msal = require("@azure/msal-node");
const azureCloudEndpoint_1 = require("../../Enums/azureCloudEndpoint");
const internal_1 = require("../../internal");
class TelemetryConfig {
    /**
     * Base implementation for the TelemetryConfig constructor.
     * Constructs a telemetry configuration with user-defined token provider,
     * or with the credentials for user-defined Kusto cluster and table names.
     * @param ingestAtLevel Kusto ingestion security level for the execution environment.
     * @param region Geographic information, e.g. "West US".
     * @param removeUserContent Whether to remove all potential user created content.
     * @param tenantIdOrTokenProvider The tenant (directory) ID of the Azure AD application registration; or a token provider defined by user.
     * @param clientId The client ID of the application.
     * @param secret The client secret of the application.
     * @param clusterName Kusto cluster name.
     * @param databaseName Kusto database name.
     * @param infoTable Table for storing informational logs.
     * @param warningTable Table for storing warning logs.
     * @param errorTable Table for storing error logs.
     */
    constructor(ingestAtLevel, region = null, removeUserContent = false, tenantIdOrTokenProvider, clientId, secret, clusterName, databaseName, cloudInstance = internal_1.azureCloudEndpoint.AzurePublic, infoTable, warningTable, errorTable) {
        /**
         * Default Kusto database log table names.
         */
        this.cdmInfoLogTable = 'infoLogs';
        this.cdmWarningLogTable = 'warningLogs';
        this.cdmErrorLogTable = 'errorLogs';
        /**
         * Kusto table for informational logs.
         */
        this.kustoInfoLogTable = this.cdmInfoLogTable;
        /**
         * Kusto table for warning logs.
         */
        this.kustoWarningLogTable = this.cdmWarningLogTable;
        /**
         * Kusto table for error logs.
         */
        this.kustoErrorLogTable = this.cdmErrorLogTable;
        if (tenantIdOrTokenProvider) {
            // Constructs with AAD App credentials
            if (typeof tenantIdOrTokenProvider === 'string') {
                this.tenantId = tenantIdOrTokenProvider;
                this.clientId = clientId;
                this.secret = secret;
            }
            // Constructs with user-defined token provider
            else {
                this.tokenProvider = this.tokenProvider;
            }
        }
        this.kustoClusterName = clusterName;
        this.kustoDatabaseName = databaseName;
        if (infoTable && warningTable && errorTable) {
            this.kustoInfoLogTable = infoTable;
            this.kustoWarningLogTable = warningTable;
            this.kustoErrorLogTable = errorTable;
        }
        this.ingestAtLevel = ingestAtLevel;
        this.region = region;
        this.removeUserContent = removeUserContent;
        this.cloudInstance = cloudInstance;
    }
    /**
     * @internal
     * Get the authentication token either using AAD App credentials or user-defined token provider.
     * @returns An authentication token.
     */
    getAuthenticationToken() {
        return __awaiter(this, void 0, void 0, function* () {
            // User-defined token provider
            if (this.tokenProvider) {
                return this.tokenProvider.getToken();
            }
            // Get token by supplying AAD App credentials
            else if (this.tenantId && this.clientId && this.secret && this.kustoClusterName && this.kustoDatabaseName
                && this.kustoInfoLogTable && this.kustoWarningLogTable && this.kustoErrorLogTable) {
                const result = yield this.generateKustoToken();
                return `${result.tokenType} ${result.accessToken}`;
            }
            // Throw an exception if neither method is configured
            else {
                throw new Error('Failed to get authentication token: No method configured to provide a token.');
            }
        });
    }
    /**
     * Build context when users make the first call. Need to ensure client Id, tenant and secret are not null.
     */
    buildContext() {
        if (this.context === undefined) {
            const clientConfig = {
                auth: {
                    clientId: this.clientId,
                    authority: `${azureCloudEndpoint_1.AzureCloudEndpointConvertor.azureCloudEndpointToURL(this.cloudInstance)}${this.tenantId}`,
                    clientSecret: this.secret
                }
            };
            this.context = new msal.ConfidentialClientApplication(clientConfig);
        }
    }
    /**
     * Generate a Bearer token for accessing the Kusto resource using MSAL.
     * @returns The authentication result.
     */
    generateKustoToken() {
        return __awaiter(this, void 0, void 0, function* () {
            // Define the resource scope to be the current Kusto cluster
            const scopes = [`https://${this.kustoClusterName}.kusto.windows.net/.default`];
            // Authenticate with AAD App credentials
            this.buildContext();
            // Acquire token using MSAL
            return new Promise((resolve, reject) => {
                const clientCredentialRequest = {
                    scopes,
                };
                this.context.acquireTokenByClientCredential(clientCredentialRequest).then((response) => {
                    if (response.accessToken && response.accessToken.length !== 0 && response.tokenType) {
                        resolve(response);
                    }
                    reject(Error('Received invalid Kusto authentication result. The result might be null, or missing HTTP authorization header from the authentication result.'));
                }).catch((error) => {
                    reject(Error('There was an error while acquiring Kusto authorization Token with client ID/secret authentication. Exception:' + JSON.stringify(error)));
                });
            });
        });
    }
}
exports.TelemetryConfig = TelemetryConfig;
//# sourceMappingURL=TelemetryConfig.js.map