/*!
 * Copyright (C) Microsoft Corporation. All rights reserved.
 */
import { generateGuid } from '@microsoft/power-apps-common/utils';
import { getConnectorAsync } from '../services/index.js';
import { connectionFirstPartyLoginAsync, testConnectionAsync, } from '../services/connectivity/ApimService.js';
import { deleteConnectionAsync, putConnectionAsync, validateSsoEligible, } from '../services/connectivity/ConnectivityService.js';
/**
 * Creates and authenticates a new SSO connection for a first-party connector.
 *
 * Full 4-step flow:
 *  1. GET connector definition → validate SSO eligibility (no required user params)
 *  2. PUT new connection with $expand=ConsentLink → receives firstPartyLoginUri in response
 *  3. POST firstPartyLoginUri with OBO access token → authenticate the connection
 *  4. POST testConnection → verify the connection is working
 *
 * The OBO token is acquired for the apihub audience (consentServerResource),
 * which equals apiHubRuntimeAudience per PowerApps-Client region configs.
 *
 * If steps 3–4 fail, the newly-created connection is deleted before rethrowing,
 * so no orphaned connections are left in the environment.
 *
 * @param context - Shared action context (auth, region, logger, etc.).
 * @returns       The authenticated and tested {@link Connection}.
 */
export async function createConnectionAsync(context) {
    const { actionsParams, authProvider, logger } = context;
    const connectorId = normalizeConnectorId(actionsParams.connectorId);
    // 1. Fetch connector definition and validate SSO eligibility
    const connector = await getConnectorAsync(connectorId, logger);
    if (!connector) {
        throw new Error(`Failed to fetch connector '${connectorId}': connector not found`);
    }
    const ssoSetName = validateSsoEligible(connector, connectorId);
    // 2. PUT the new connection with $expand=ConsentLink to receive firstPartyLoginUri in response
    const connectionId = generateGuid();
    const displayName = actionsParams.displayName ?? connector.properties?.displayName ?? connectorId;
    const connection = await putConnectionAsync(connectorId, connectionId, displayName, logger, ssoSetName);
    // Steps 3–4 may fail — delete the connection if so to avoid orphans
    try {
        const firstPartyLoginUri = connection.properties.consentInfo?.firstPartyLoginUri;
        if (!firstPartyLoginUri) {
            throw new Error(`Connector '${connectorId}' did not return a firstPartyLoginUri — ` +
                `it may not support silent SSO. Use an interactive connection flow instead.`);
        }
        // 3. POST OBO token to firstPartyLoginUri → authenticate the connection
        await connectionFirstPartyLoginAsync(authProvider, firstPartyLoginUri, logger);
        // 4. POST testConnection → verify the connection works
        await testConnectionAsync(connection, logger);
    }
    catch (authOrTestError) {
        logger.trackActivityEvent('createConnection.cleanup', { connectorId, connectionId });
        try {
            await deleteConnectionAsync(connectorId, connectionId, logger);
            logger.trackActivityEvent('createConnection.cleanup.done', { connectorId, connectionId });
        }
        catch (deleteError) {
            logger.trackActivityEvent('createConnection.cleanup.failed', {
                connectorId,
                connectionId,
                error: String(deleteError),
            });
        }
        throw authOrTestError;
    }
    return connection;
}
/**
 * Normalizes a connector ID to the APIM shared form.
 * "office365" → "shared_office365"; "shared_office365" → "shared_office365".
 */
function normalizeConnectorId(connectorId) {
    return connectorId.startsWith('shared_') ? connectorId : `shared_${connectorId}`;
}
//# sourceMappingURL=CreateConnection.js.map