/*! @azure/msal-common v16.5.1 2026-04-21 */
'use strict';
import { CACHE_KEY_SEPARATOR, CACHE_ACCOUNT_TYPE_GENERIC, CACHE_ACCOUNT_TYPE_ADFS, CACHE_ACCOUNT_TYPE_MSSTS } from '../../utils/Constants.mjs';
import { buildClientInfo } from '../../account/ClientInfo.mjs';
import { buildTenantProfile } from '../../account/AccountInfo.mjs';
import { createClientAuthError } from '../../error/ClientAuthError.mjs';
import { AuthorityType } from '../../authority/AuthorityType.mjs';
import { getTenantIdFromIdTokenClaims } from '../../account/TokenClaims.mjs';
import { ProtocolMode } from '../../authority/ProtocolMode.mjs';
import { invalidCacheEnvironment } from '../../error/ClientAuthErrorCodes.mjs';

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Generate Account Id key component as per the schema: <home_account_id>-<environment>
 */
function generateAccountId(accountEntity) {
    const accountId = [
        accountEntity.homeAccountId,
        accountEntity.environment,
    ];
    return accountId.join(CACHE_KEY_SEPARATOR).toLowerCase();
}
/**
 * Returns the AccountInfo interface for this account.
 */
function getAccountInfo(accountEntity) {
    const tenantProfiles = accountEntity.tenantProfiles || [];
    // Ensure at least the home tenant profile exists
    if (tenantProfiles.length === 0 &&
        accountEntity.realm &&
        accountEntity.localAccountId) {
        tenantProfiles.push(buildTenantProfile(accountEntity.homeAccountId, accountEntity.localAccountId, accountEntity.realm));
    }
    return {
        homeAccountId: accountEntity.homeAccountId,
        environment: accountEntity.environment,
        tenantId: accountEntity.realm,
        username: accountEntity.username,
        localAccountId: accountEntity.localAccountId,
        loginHint: accountEntity.loginHint,
        name: accountEntity.name,
        nativeAccountId: accountEntity.nativeAccountId,
        authorityType: accountEntity.authorityType,
        // Deserialize tenant profiles array into a Map
        tenantProfiles: new Map(tenantProfiles.map((tenantProfile) => {
            return [tenantProfile.tenantId, tenantProfile];
        })),
        dataBoundary: accountEntity.dataBoundary,
    };
}
/**
 * Returns true if the account entity is in single tenant format (outdated), false otherwise
 */
function isSingleTenant(accountEntity) {
    return !accountEntity.tenantProfiles;
}
/**
 * Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
 * @param accountDetails
 */
function createAccountEntity(accountDetails, authority, base64Decode) {
    let authorityType;
    if (authority.authorityType === AuthorityType.Adfs) {
        authorityType = CACHE_ACCOUNT_TYPE_ADFS;
    }
    else if (authority.protocolMode === ProtocolMode.OIDC) {
        authorityType = CACHE_ACCOUNT_TYPE_GENERIC;
    }
    else {
        authorityType = CACHE_ACCOUNT_TYPE_MSSTS;
    }
    let clientInfo;
    let dataBoundary;
    if (accountDetails.clientInfo && base64Decode) {
        clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode);
        if (clientInfo.xms_tdbr) {
            dataBoundary = clientInfo.xms_tdbr === "EU" ? "EU" : "None";
        }
    }
    const env = accountDetails.environment ||
        (authority && authority.getPreferredCache());
    if (!env) {
        throw createClientAuthError(invalidCacheEnvironment);
    }
    /*
     * In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
     * In most cases it will contain a single email. This field should not be relied upon if a custom
     * policy is configured to return more than 1 email.
     */
    const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
        accountDetails.idTokenClaims?.upn;
    const email = accountDetails.idTokenClaims?.emails
        ? accountDetails.idTokenClaims.emails[0]
        : null;
    const username = preferredUsername || email || "";
    const loginHint = accountDetails.idTokenClaims?.login_hint;
    const realm = clientInfo?.utid ||
        getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
        ""; // non-AAD scenarios can have empty realm
    // How do you account for MSA CID here?
    const localAccountId = clientInfo?.uid ||
        accountDetails.idTokenClaims?.oid ||
        accountDetails.idTokenClaims?.sub ||
        "";
    let tenantProfiles;
    if (accountDetails.tenantProfiles) {
        tenantProfiles = accountDetails.tenantProfiles;
    }
    else {
        const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, localAccountId, realm, accountDetails.idTokenClaims);
        tenantProfiles = [tenantProfile];
    }
    return {
        homeAccountId: accountDetails.homeAccountId,
        environment: env,
        realm: realm,
        localAccountId: localAccountId,
        username: username,
        authorityType: authorityType,
        loginHint: loginHint,
        clientInfo: accountDetails.clientInfo,
        name: accountDetails.idTokenClaims?.name || "",
        lastModificationTime: undefined,
        lastModificationApp: undefined,
        cloudGraphHostName: accountDetails.cloudGraphHostName,
        msGraphHost: accountDetails.msGraphHost,
        nativeAccountId: accountDetails.nativeAccountId,
        tenantProfiles: tenantProfiles,
        dataBoundary,
    };
}
/**
 * Creates an AccountEntity object from AccountInfo
 * @param accountInfo
 * @param cloudGraphHostName
 * @param msGraphHost
 * @returns
 */
function createAccountEntityFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
    // Serialize tenant profiles map into an array
    const tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
    // Ensure at least the home tenant profile exists
    if (tenantProfiles.length === 0 &&
        accountInfo.tenantId &&
        accountInfo.localAccountId) {
        tenantProfiles.push(buildTenantProfile(accountInfo.homeAccountId, accountInfo.localAccountId, accountInfo.tenantId, accountInfo.idTokenClaims));
    }
    return {
        authorityType: accountInfo.authorityType || CACHE_ACCOUNT_TYPE_GENERIC,
        homeAccountId: accountInfo.homeAccountId,
        localAccountId: accountInfo.localAccountId,
        nativeAccountId: accountInfo.nativeAccountId,
        realm: accountInfo.tenantId,
        environment: accountInfo.environment,
        username: accountInfo.username,
        loginHint: accountInfo.loginHint,
        name: accountInfo.name,
        cloudGraphHostName: cloudGraphHostName,
        msGraphHost: msGraphHost,
        tenantProfiles: tenantProfiles,
        dataBoundary: accountInfo.dataBoundary,
    };
}
/**
 * Generate HomeAccountId from server response
 * @param serverClientInfo
 * @param authType
 */
function generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, correlationId, idTokenClaims) {
    // since ADFS/DSTS do not have tid and does not set client_info
    if (!(authType === AuthorityType.Adfs || authType === AuthorityType.Dsts)) {
        // for cases where there is clientInfo
        if (serverClientInfo) {
            try {
                const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
                if (clientInfo.uid && clientInfo.utid) {
                    return `${clientInfo.uid}.${clientInfo.utid}`;
                }
            }
            catch (e) { }
        }
        logger.warning("No client info in response", correlationId);
    }
    // default to "sub" claim
    return idTokenClaims?.sub || "";
}
/**
 * Validates an entity: checks for all expected params
 * @param entity
 */
function isAccountEntity(entity) {
    if (!entity) {
        return false;
    }
    return (entity.hasOwnProperty("homeAccountId") &&
        entity.hasOwnProperty("environment") &&
        entity.hasOwnProperty("realm") &&
        entity.hasOwnProperty("localAccountId") &&
        entity.hasOwnProperty("username") &&
        entity.hasOwnProperty("authorityType"));
}

export { createAccountEntity, createAccountEntityFromAccountInfo, generateAccountId, generateHomeAccountId, getAccountInfo, isAccountEntity, isSingleTenant };
//# sourceMappingURL=AccountEntityUtils.mjs.map
