/*! @azure/msal-browser v3.11.1 2024-03-27 */
'use strict';
import { DEFAULT_CRYPTO_IMPLEMENTATION, PerformanceEvents, TimeUtils } from '@azure/msal-common';
import { InteractionType } from '../utils/BrowserConstants.mjs';
import { CryptoOps } from '../crypto/CryptoOps.mjs';
import { NestedAppAuthAdapter } from '../naa/mapping/NestedAppAuthAdapter.mjs';
import { NestedAppAuthError } from '../error/NestedAppAuthError.mjs';
import { EventHandler } from '../event/EventHandler.mjs';
import { EventType } from '../event/EventType.mjs';

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
class NestedAppAuthController {
    constructor(operatingContext) {
        this.operatingContext = operatingContext;
        const proxy = this.operatingContext.getBridgeProxy();
        if (proxy !== undefined) {
            this.bridgeProxy = proxy;
        }
        else {
            throw new Error("unexpected: bridgeProxy is undefined");
        }
        // Set the configuration.
        this.config = operatingContext.getConfig();
        // Initialize logger
        this.logger = this.operatingContext.getLogger();
        // Initialize performance client
        this.performanceClient = this.config.telemetry.client;
        // Initialize the crypto class.
        this.browserCrypto = operatingContext.isBrowserEnvironment()
            ? new CryptoOps(this.logger, this.performanceClient)
            : DEFAULT_CRYPTO_IMPLEMENTATION;
        this.eventHandler = new EventHandler(this.logger, this.browserCrypto);
        this.nestedAppAuthAdapter = new NestedAppAuthAdapter(this.config.auth.clientId, this.config.auth.clientCapabilities, this.browserCrypto, this.logger);
    }
    getBrowserStorage() {
        throw NestedAppAuthError.createUnsupportedError();
    }
    getEventHandler() {
        return this.eventHandler;
    }
    static async createController(operatingContext) {
        const controller = new NestedAppAuthController(operatingContext);
        return Promise.resolve(controller);
    }
    initialize() {
        // do nothing not required by this controller
        return Promise.resolve();
    }
    ensureValidRequest(request) {
        if (request?.correlationId) {
            return request;
        }
        return {
            ...request,
            correlationId: this.browserCrypto.createNewGuid(),
        };
    }
    async acquireTokenInteractive(request) {
        const validRequest = this.ensureValidRequest(request);
        this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_START, InteractionType.Popup, validRequest);
        const atPopupMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenPopup, validRequest.correlationId);
        atPopupMeasurement?.add({ nestedAppAuthRequest: true });
        try {
            const naaRequest = this.nestedAppAuthAdapter.toNaaTokenRequest(validRequest);
            const reqTimestamp = TimeUtils.nowSeconds();
            const response = await this.bridgeProxy.getTokenInteractive(naaRequest);
            const result = this.nestedAppAuthAdapter.fromNaaTokenResponse(naaRequest, response, reqTimestamp);
            this.operatingContext.setActiveAccount(result.account);
            this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Popup, result);
            atPopupMeasurement.add({
                accessTokenSize: result.accessToken.length,
                idTokenSize: result.idToken.length,
            });
            atPopupMeasurement.end({
                success: true,
                requestId: result.requestId,
            });
            return result;
        }
        catch (e) {
            const error = this.nestedAppAuthAdapter.fromBridgeError(e);
            this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Popup, null, e);
            atPopupMeasurement.end({
                success: false,
            }, e);
            throw error;
        }
    }
    async acquireTokenSilentInternal(request) {
        const validRequest = this.ensureValidRequest(request);
        this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_START, InteractionType.Silent, validRequest);
        const ssoSilentMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.SsoSilent, validRequest.correlationId);
        ssoSilentMeasurement?.increment({
            visibilityChangeCount: 0,
        });
        ssoSilentMeasurement?.add({
            nestedAppAuthRequest: true,
        });
        try {
            const naaRequest = this.nestedAppAuthAdapter.toNaaTokenRequest(validRequest);
            const reqTimestamp = TimeUtils.nowSeconds();
            const response = await this.bridgeProxy.getTokenSilent(naaRequest);
            const result = this.nestedAppAuthAdapter.fromNaaTokenResponse(naaRequest, response, reqTimestamp);
            this.operatingContext.setActiveAccount(result.account);
            this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Silent, result);
            ssoSilentMeasurement?.add({
                accessTokenSize: result.accessToken.length,
                idTokenSize: result.idToken.length,
            });
            ssoSilentMeasurement?.end({
                success: true,
                requestId: result.requestId,
            });
            return result;
        }
        catch (e) {
            const error = this.nestedAppAuthAdapter.fromBridgeError(e);
            this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Silent, null, e);
            ssoSilentMeasurement?.end({
                success: false,
            }, e);
            throw error;
        }
    }
    async acquireTokenPopup(request) {
        return this.acquireTokenInteractive(request);
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    acquireTokenRedirect(request) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    async acquireTokenSilent(silentRequest) {
        return this.acquireTokenSilentInternal(silentRequest);
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    acquireTokenByCode(request // eslint-disable-line @typescript-eslint/no-unused-vars
    ) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    acquireTokenNative(request, apiId, // eslint-disable-line @typescript-eslint/no-unused-vars
    accountId // eslint-disable-line @typescript-eslint/no-unused-vars
    ) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    acquireTokenByRefreshToken(commonRequest, // eslint-disable-line @typescript-eslint/no-unused-vars
    silentRequest // eslint-disable-line @typescript-eslint/no-unused-vars
    ) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    /**
     * Adds event callbacks to array
     * @param callback
     */
    addEventCallback(callback) {
        return this.eventHandler.addEventCallback(callback);
    }
    /**
     * Removes callback with provided id from callback array
     * @param callbackId
     */
    removeEventCallback(callbackId) {
        this.eventHandler.removeEventCallback(callbackId);
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    addPerformanceCallback(callback) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    removePerformanceCallback(callbackId) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    enableAccountStorageEvents() {
        throw NestedAppAuthError.createUnsupportedError();
    }
    disableAccountStorageEvents() {
        throw NestedAppAuthError.createUnsupportedError();
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    getAccount(accountFilter) {
        throw NestedAppAuthError.createUnsupportedError();
        // TODO: Look at standard implementation
    }
    getAccountByHomeId(homeAccountId) {
        const currentAccount = this.operatingContext.getActiveAccount();
        if (currentAccount !== undefined) {
            if (currentAccount.homeAccountId === homeAccountId) {
                return this.nestedAppAuthAdapter.fromNaaAccountInfo(currentAccount);
            }
            else {
                return null;
            }
        }
        else {
            return null;
        }
    }
    getAccountByLocalId(localId) {
        const currentAccount = this.operatingContext.getActiveAccount();
        if (currentAccount !== undefined) {
            if (currentAccount.localAccountId === localId) {
                return this.nestedAppAuthAdapter.fromNaaAccountInfo(currentAccount);
            }
            else {
                return null;
            }
        }
        else {
            return null;
        }
    }
    getAccountByUsername(userName) {
        const currentAccount = this.operatingContext.getActiveAccount();
        if (currentAccount !== undefined) {
            if (currentAccount.username === userName) {
                return this.nestedAppAuthAdapter.fromNaaAccountInfo(currentAccount);
            }
            else {
                return null;
            }
        }
        else {
            return null;
        }
    }
    getAllAccounts() {
        const currentAccount = this.operatingContext.getActiveAccount();
        if (currentAccount !== undefined) {
            return [
                this.nestedAppAuthAdapter.fromNaaAccountInfo(currentAccount),
            ];
        }
        else {
            return [];
        }
    }
    handleRedirectPromise(hash // eslint-disable-line @typescript-eslint/no-unused-vars
    ) {
        return Promise.resolve(null);
    }
    loginPopup(request // eslint-disable-line @typescript-eslint/no-unused-vars
    ) {
        if (request !== undefined) {
            return this.acquireTokenInteractive(request);
        }
        else {
            throw NestedAppAuthError.createUnsupportedError();
        }
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    loginRedirect(request) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    logout(logoutRequest) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    logoutRedirect(logoutRequest // eslint-disable-line @typescript-eslint/no-unused-vars
    ) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    logoutPopup(logoutRequest // eslint-disable-line @typescript-eslint/no-unused-vars
    ) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    ssoSilent(
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    request) {
        return this.acquireTokenSilentInternal(request);
    }
    getTokenCache() {
        throw NestedAppAuthError.createUnsupportedError();
    }
    /**
     * Returns the logger instance
     */
    getLogger() {
        return this.logger;
    }
    /**
     * Replaces the default logger set in configurations with new Logger with new configurations
     * @param logger Logger instance
     */
    setLogger(logger) {
        this.logger = logger;
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    setActiveAccount(account) {
        /*
         * StandardController uses this to allow the developer to set the active account
         * in the nested app auth scenario the active account is controlled by the app hosting the nested app
         */
        this.logger.warning("nestedAppAuth does not support setActiveAccount");
        return;
    }
    getActiveAccount() {
        const currentAccount = this.operatingContext.getActiveAccount();
        if (currentAccount !== undefined) {
            return this.nestedAppAuthAdapter.fromNaaAccountInfo(currentAccount);
        }
        else {
            return null;
        }
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    initializeWrapperLibrary(sku, version) {
        /*
         * Standard controller uses this to set the sku and version of the wrapper library in the storage
         * we do nothing here
         */
        return;
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    setNavigationClient(navigationClient) {
        this.logger.warning("setNavigationClient is not supported in nested app auth");
    }
    getConfiguration() {
        return this.config;
    }
    isBrowserEnv() {
        return this.operatingContext.isBrowserEnvironment();
    }
    getBrowserCrypto() {
        return this.browserCrypto;
    }
    getPerformanceClient() {
        throw NestedAppAuthError.createUnsupportedError();
    }
    getRedirectResponse() {
        throw NestedAppAuthError.createUnsupportedError();
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    async clearCache(logoutRequest) {
        throw NestedAppAuthError.createUnsupportedError();
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    async hydrateCache(
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    result, 
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    request) {
        throw NestedAppAuthError.createUnsupportedError();
    }
}

export { NestedAppAuthController };
//# sourceMappingURL=NestedAppAuthController.mjs.map
