"use strict";
/**
 * @Copyright (c) Microsoft Corporation.  All rights reserved.
 */
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var sp_core_library_1 = require("@microsoft/sp-core-library");
var sp_diagnostics_1 = require("@microsoft/sp-diagnostics");
var sp_telemetry_1 = require("@ms/sp-telemetry");
var DebugManager_1 = require("../debug/DebugManager");
var DebugStatus_1 = require("../debug/DebugStatus");
var showBrowserDevToolsWarning_1 = require("../DeveloperTools/BrowserDeveloperToolsWarning/showBrowserDevToolsWarning");
var developerToolsLoader = tslib_1.__importStar(require("../DeveloperTools/DeveloperToolsLoader"));
var DeveloperToolsProxy_1 = tslib_1.__importDefault(require("../DeveloperTools/DeveloperToolsProxy"));
var LocaleStore_1 = tslib_1.__importDefault(require("../stores/LocaleStore"));
var ManifestStore_1 = tslib_1.__importDefault(require("../stores/ManifestStore"));
var createRootScope_1 = require("../tiny/common/createRootScope");
var killSwitches_1 = require("../tiny/common/killSwitches");
var SPComponentLoader_1 = require("../tiny/componentLoader/SPComponentLoader");
var RequireLoader_1 = require("../tiny/requireLoader/RequireLoader");
var ManifestStore_2 = require("../tiny/store/ManifestStore");
var componentConstants = tslib_1.__importStar(require("../utilities/componentConstants"));
var ResourceUrlChecker_1 = tslib_1.__importDefault(require("../utilities/ResourceUrlChecker"));
var SPLoaderFlights_1 = tslib_1.__importDefault(require("../utilities/SPLoaderFlights"));
var strings = tslib_1.__importStar(require("./Starter.resx"));
// !!! Show the developer tools warning as soon as the page loads !!!
if (!DEBUG && !DEPRECATED_UNIT_TEST) {
    showBrowserDevToolsWarning_1.showBrowserDevToolsWarning();
}
var ARIA_DISABLE_TELEMETRY_LOGGING_FLIGHT_ID = 1190;
var DEBUG_FLIGHTS_QUERY_PARAM = 'debugFlights';
var DEBUG_KILLSWITCHES_QUERY_PARAM = 'debugKillSwitches';
var COMPONENT_LOADER_GLOBAL_VARIABLE = '_spComponentLoader';
// QoS constants
var startQosScenarioName = 'SPComponentLoader.start';
var syntheticStartQosScenarioName = 'SyntheticEvent.SPComponentLoader.start';
/**
 * Bootstrapper for the application
 * @internal
 */
var SPStarter = /** @class */ (function () {
    function SPStarter() {
    }
    /**
     * Sets a map with the bundled components. These components will be added to the component loader
     * during initialization, so they won't need to be loaded afterwards.
     * The map is of the form `componentId: string -> component: Object`
     *
     * @internal
     */
    SPStarter._setBundledComponents = function (bundledComponents) {
        if (!SPStarter._bundledComponents) {
            SPStarter._bundledComponents = bundledComponents;
        }
        else {
            throw new Error('Bundled components can be only set once'); // TODO mpasarin: Localize
        }
    };
    /**
     * Raise the `onSecondFlush` event to resume starting with the full set of preloaded data.
     * This is called by the page scripts to resume loading the framework. Do not call it from your own code.
     *
     * @param preloadedData - Full set of preloaded data for the current session.
     */
    SPStarter.startSecondFlush = function (preloadedData) {
        sp_telemetry_1._PerformanceLogger.setPerformanceProperty('SPStarter.startSecondFlush');
        window[COMPONENT_LOADER_GLOBAL_VARIABLE].registerManifests(preloadedData.manifests);
        sp_core_library_1._SPEventManager.instance.raiseStickyEvent('onSecondFlush', preloadedData);
    };
    /**
     * This is called by the page scripts to start loading the framework. Do not call it from your own code.
     * @param preloadedData - Data initialized on the page by the server.
     * @param handleFailure - Error handler function provided by the server to execute if there is SPFx can't be loaded.
     *  It may redirect to an error page or log error data in the console.
     * @param debugData - This parameter is used when the loader initializes a debug loader and
     *  should never be provided by any external callers.
     * @param isFirstFlush - Indicates whether the caller intends to call `startSecondFlush` to finish starting SPFx.
     */
    SPStarter.start = function (preloadedData, handleFailure, debugData, isFirstFlush) {
        var _this = this;
        sp_telemetry_1._PerformanceLogger.devMark('SPStarter.start');
        var _a = preloadedData.clientSideApplicationId, clientSideApplicationId = _a === void 0 ? '00000000-0000-0000-0000-000000000000' : _a, spPageContextInfo = preloadedData.spPageContextInfo;
        var correlationId = spPageContextInfo.CorrelationId;
        // Initialize flights and killswitches
        this._initializeFlightsAndKillswitches(spPageContextInfo);
        if (debugData && !killSwitches_1.isDangerouslyEnableDebugKSActivated()) {
            DebugStatus_1.DebugStatus.dangerouslyEnableDebug();
        }
        var serviceScope = createRootScope_1.createRootScope(spPageContextInfo);
        ManifestStore_1.default.instance = new ManifestStore_2.OldManifestStoreShim(serviceScope, spPageContextInfo.webAbsoluteUrl);
        var spLoader = require('../index');
        ResourceUrlChecker_1.default.useSecondaryCdn = SPStarter.useSecondaryCdn;
        var componentLoader = new SPComponentLoader_1.SPComponentLoader({
            preloadedData: preloadedData,
            serviceScope: serviceScope,
            bundledComponents: SPStarter._getBundledComponents(),
            ctor: RequireLoader_1.RequireLoader,
            debugData: debugData || {},
            useSecondaryCdn: SPStarter.useSecondaryCdn
        });
        var qosMonitor = undefined;
        var wwQosMonitor = undefined;
        var isWorkerReliabilityFlightEnabled = sp_core_library_1._SPFlight.isEnabled(60283 /* Web worker reliability flight. */);
        try {
            // Initialize telemetry
            sp_core_library_1.Log._initialize(new sp_diagnostics_1._LogHandler());
            SPStarter._initializeEnvironment(clientSideApplicationId);
            sp_core_library_1.Session._initialize({
                clientSideApplicationId: clientSideApplicationId,
                applicationId: correlationId
            });
            SPStarter._initializeTelemetry(preloadedData);
            sp_telemetry_1._PerformanceLogger.markSpLoaderStart();
            // Ensure that Telemetry logs in real time, if not already doing so
            window.setTimeout(function () {
                SPStarter._logDataInRealTime();
            }, SPStarter._realTimeProcessingWaitTime);
            qosMonitor = new sp_diagnostics_1._QosMonitor(startQosScenarioName);
            if (isWorkerReliabilityFlightEnabled) {
                wwQosMonitor = new sp_diagnostics_1._QosMonitor(syntheticStartQosScenarioName);
            }
            // Set locale
            LocaleStore_1.default.setLocale(spPageContextInfo.currentUICultureName);
            // Initialize the proxies
            componentLoader._initialize(preloadedData, SPStarter._getBundledComponents(), debugData || {});
            spLoader.SPComponentLoader._initialize(componentLoader);
            window[COMPONENT_LOADER_GLOBAL_VARIABLE] = spLoader.SPComponentLoader;
        }
        catch (error) {
            return Promise.reject(error);
        }
        return DebugManager_1.DebugManager.initialize(componentLoader, debugData)
            .then(function (debugLoadResult) {
            if (debugLoadResult.debugLoader) {
                // If we're loading a debug loader, call "start" on it instead of continuing with the normal initialization
                // flow
                componentLoader._unloadComponents();
                return debugLoadResult.debugLoader.start(preloadedData, handleFailure, debugLoadResult, isFirstFlush);
            }
            // Load the dev tools after the debug loader to reference the right diagnostics component
            DeveloperToolsProxy_1.default.initialize(developerToolsLoader, serviceScope);
            // Only run the experiment if the tiny loader is running
            if (SPLoaderFlights_1.default._isOptimisticPreloadEnabled()) {
                spLoader.SPComponentLoader._preloadComponents();
            }
            if (SPLoaderFlights_1.default._isMinimalStartFlightEnabled() && !isFirstFlush) {
                sp_core_library_1._SPEventManager.instance.raiseStickyEvent('onSecondFlush', preloadedData);
            }
            var status = sp_core_library_1._SPExperiment.getVariantAndLogExposure(90033 /* PagesClientServerRequestOptimzationExperiment */) === 1;
            sp_telemetry_1._PerformanceLogger.trackExperiment(90033, status ? 'Treatment' : 'Control');
            // Start the application
            return spLoader.SPComponentLoader._startApplication(preloadedData);
        })
            .then(function (application) {
            qosMonitor.writeSuccess();
            if (isWorkerReliabilityFlightEnabled) {
                wwQosMonitor.writeSuccess();
            }
            // Log telemetry data from buffers to the server
            SPStarter._logDataInRealTime();
            return application;
        })
            .catch(function (error) {
            if (qosMonitor) {
                if (error.message === 'Out of stack space') {
                    qosMonitor.writeExpectedFailure('ConflictingPolyfill', error);
                    if (isWorkerReliabilityFlightEnabled) {
                        wwQosMonitor.writeExpectedFailure('ConflictingPolyfill', error);
                    }
                }
                else {
                    qosMonitor.writeUnexpectedFailure('StartApplication', error);
                    if (isWorkerReliabilityFlightEnabled) {
                        wwQosMonitor.writeUnexpectedFailure('StartApplication', error);
                    }
                }
            }
            SPStarter._logDataInRealTime();
            return _this.handleError(error, strings.loaderUserFriendlyError, sp_telemetry_1._Telemetry.isInitialized ? 'ClientError' : 'ClientErrorBeforeTelemetry', correlationId, preloadedData);
        });
    };
    SPStarter._logDataInRealTime = function () {
        if (!SPStarter._isTelemetryDisabled() && !SPStarter._isTelemetryLoggingInRealTime) {
            sp_telemetry_1._Telemetry.startRealTimeProcessing();
            SPStarter._isTelemetryLoggingInRealTime = true;
        }
    };
    /**
     * Returns the bundled components variable, after checking it exists.
     * If it doesn't exist, it throws an error as SPFx cannot be initialized without it.
     */
    SPStarter._getBundledComponents = function () {
        sp_core_library_1.Validate.isNotNullOrUndefined(SPStarter._bundledComponents, 'bundledComponents');
        return SPStarter._bundledComponents;
    };
    SPStarter._initializeEnvironment = function (clientSideApplicationId) {
        var type;
        /* tslint:disable:no-string-literal */
        if (window.location.hostname === 'localhost' ||
            (window['ENVIRONMENTTYPE'] && window['ENVIRONMENTTYPE'] === 'Local')) {
            /* tslint:enable:no-string-literal */
            type = sp_core_library_1.EnvironmentType.Local;
        }
        else if (clientSideApplicationId === 'eb4b666b-5c29-4dad-9a99-23613f21a2b7') {
            // 'eb4b666b-5c29-4dad-9a99-23613f21a2b7' is the classic page application id.
            type = sp_core_library_1.EnvironmentType.ClassicSharePoint;
        }
        else {
            type = sp_core_library_1.EnvironmentType.SharePoint;
        }
        sp_core_library_1.Environment._initialize({ type: type });
    };
    SPStarter._initializeTelemetry = function (preloadedData) {
        var _a;
        if (SPStarter._isTelemetryDisabled()) {
            return;
        }
        var buildNumber = preloadedData.buildNumber, clientSideApplicationId = preloadedData.clientSideApplicationId, listItemId = preloadedData.listItemId, manifests = preloadedData.manifests, spPageContextInfo = preloadedData.spPageContextInfo;
        var listItemUniqueId = listItemId || ((_a = preloadedData.item) === null || _a === void 0 ? void 0 : _a.UniqueId);
        var CorrelationId = spPageContextInfo.CorrelationId, listId = spPageContextInfo.listId, siteId = spPageContextInfo.siteId, webId = spPageContextInfo.webId;
        // The first manifest is always the application's manifest.
        sp_telemetry_1._Telemetry.initialize(manifests[0].alias, spPageContextInfo, buildNumber, clientSideApplicationId, SPStarter._isConsoleLogEnabled(), listItemUniqueId);
        sp_diagnostics_1._Diagnostics.initialize({
            enableConsoleLog: SPStarter._isConsoleLogEnabled(),
            siteId: siteId,
            webId: webId,
            listId: listId,
            listItemUniqueId: listItemId,
            correlationId: CorrelationId
        });
    };
    SPStarter._initializeFlightsAndKillswitches = function (spPageContextInfo) {
        // Initialize flights and killswitches with the data from the server
        sp_core_library_1._SPFlight.initialize(spPageContextInfo.ExpFeatures);
        sp_core_library_1._SPKillSwitch.initialize(spPageContextInfo.killSwitches);
        // Initialize debug flights and killswitches from the query params
        var allowDebugQueryParameter = sp_core_library_1._SPFlight.isDebugFlightEnabled || sp_core_library_1.Environment.type === sp_core_library_1.EnvironmentType.Local;
        if (allowDebugQueryParameter) {
            sp_core_library_1._SPFlight.setDebugFlights(this._getQueryParamValue(DEBUG_FLIGHTS_QUERY_PARAM));
            sp_core_library_1._SPKillSwitch.setDebugKillswitches(this._getQueryParamValue(DEBUG_KILLSWITCHES_QUERY_PARAM));
        }
    };
    SPStarter._isQueryParameterTrue = function (name) {
        var parameterValue;
        try {
            parameterValue = this._getQueryParamValue(name) === 'true';
        }
        catch (error) {
            parameterValue = false;
        }
        return parameterValue;
    };
    SPStarter._isConsoleLogEnabled = function () {
        return SPStarter._isQueryParameterTrue('enableConsoleLog');
    };
    SPStarter._isTelemetryDisabled = function () {
        return (SPStarter._isQueryParameterTrue('disableTelemetry') ||
            sp_core_library_1._SPFlight.isEnabled(ARIA_DISABLE_TELEMETRY_LOGGING_FLIGHT_ID));
    };
    SPStarter.handleError = function (error, userFriendlyMessage, operationName, correlationId, preloadedData) {
        var errorInformation = {
            message: userFriendlyMessage,
            correlationId: correlationId,
            error: error,
            operationName: operationName
        };
        if (this._isRedirectDisabled(preloadedData)) {
            this._consoleErrorHandleFailure(errorInformation);
        }
        else {
            this._errorAspxHandleFailure(errorInformation, preloadedData);
        }
        return Promise.reject(error);
    };
    SPStarter._isRedirectDisabled = function (preloadedData) {
        return (SPStarter._isQueryParameterTrue('noredir') ||
            sp_core_library_1.Environment.type === sp_core_library_1.EnvironmentType.ClassicSharePoint || // Classic pages
            sp_core_library_1.Environment.type === sp_core_library_1.EnvironmentType.Local || // Local workbench
            preloadedData.clientSideApplicationId === componentConstants.listViewHostComponentId); // ListView application
    };
    SPStarter._consoleErrorHandleFailure = function (errorInformation) {
        console.error(errorInformation.message);
        if (errorInformation.correlationId) {
            console.error("Correlation Id: " + errorInformation.correlationId);
        }
        if (errorInformation.operationName) {
            console.error("Operation name: " + errorInformation.operationName);
        }
        if (errorInformation.error) {
            console.error(errorInformation.error.message);
            console.error("CALL STACK: " + errorInformation.error.stack);
        }
    };
    SPStarter._errorAspxHandleFailure = function (errorInformation, preloadedData) {
        var _a;
        window.location.href =
            (((_a = preloadedData.spPageContextInfo) === null || _a === void 0 ? void 0 : _a.webAbsoluteUrl) || '') +
                '/_layouts/15/error.aspx' +
                '?ErrorCorrelationId=' +
                encodeURIComponent(errorInformation.correlationId || '') +
                '&ErrorText=' +
                encodeURIComponent(errorInformation.message) +
                '&ErrorDetails=' +
                encodeURIComponent(errorInformation.error ? errorInformation.error.toString() : '') +
                '&Name=' +
                encodeURIComponent(errorInformation.operationName || 'DefaultOperation') +
                '&ErrorCategory=spfx';
    };
    SPStarter._getQueryParamValue = function (name) {
        if (!this._queryParams) {
            this._queryParams = new URLSearchParams(self.location.search);
        }
        if (this._queryParams.has(name)) {
            return this._queryParams.get(name);
        } // else returns undefined
    };
    /**
     * Value indicating if we should load scripts from the secondary CDN.
     */
    SPStarter.useSecondaryCdn = false;
    SPStarter._bundledComponents = undefined;
    SPStarter._isTelemetryLoggingInRealTime = false;
    SPStarter._realTimeProcessingWaitTime = 1 * 1000; // 1 second
    return SPStarter;
}());
exports.default = SPStarter;
//# sourceMappingURL=SPStarter.js.map