"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveToolContext = resolveToolContext;
const delegation_1 = require("../auth/delegation");
const user_1 = require("../user");
const logger_1 = require("../../lib/logger");
/** Role type priority for determining highest role type. */
const ROLE_TYPE_PRIORITY = { superadmin: 3, admin: 2, member: 1 };
/**
 * Resolve identity from any available source, load roles, mint delegation token.
 *
 * Resolution priority for userId:
 * 1. Explicit `_auth.userId` (MCP server tool path)
 * 2. Explicit `userId` parameter
 * 3. `envelope.lt.userId` (workflow/envelope path)
 * 4. `orchestratorContext.userId` (proxy activity path)
 *
 * Returns null when no identity can be resolved (anonymous/system context).
 */
async function resolveToolContext(source) {
    // Resolve userId from available sources
    const userId = source._auth?.userId ||
        source.userId ||
        source.envelope?.lt?.userId ||
        source.orchestratorContext?.userId;
    if (!userId) {
        return null;
    }
    // Build principal with roles from DB
    const principal = await resolvePrincipal(userId, source.accountType);
    // Use existing delegation token or mint a new one
    const scopes = source.scopes ?? ['mcp:tool:call'];
    const delegationToken = source._auth?.token ?? source.delegationToken ?? (0, delegation_1.createDelegationToken)(userId, scopes, 300, {
        workflowId: source.orchestratorContext?.workflowId ?? source.envelope?.lt?.parentWorkflowId,
    });
    const credentials = {
        delegationToken,
        scopes,
    };
    // Build trace from envelope and orchestrator context
    const trace = {
        originId: source.envelope?.lt?.originId,
        parentId: source.envelope?.lt?.parentId,
        workflowId: source.orchestratorContext?.workflowId,
        traceId: source.traceId,
        spanId: source.spanId,
    };
    return { principal, credentials, trace };
}
/**
 * Load a ToolPrincipal from the database.
 * Lightweight: one query for user + one for roles.
 */
async function resolvePrincipal(userId, accountType) {
    try {
        const [user, roles] = await Promise.all([
            (0, user_1.getUser)(userId),
            (0, user_1.getUserRoles)(userId),
        ]);
        // Determine highest role type
        let highestPriority = 0;
        let highestType;
        const roleNames = [];
        for (const r of roles) {
            roleNames.push(r.role);
            const priority = ROLE_TYPE_PRIORITY[r.type] ?? 0;
            if (priority > highestPriority) {
                highestPriority = priority;
                highestType = r.type;
            }
        }
        return {
            id: userId,
            type: accountType ?? user?.metadata?.account_type ?? 'user',
            displayName: user?.display_name ?? undefined,
            roles: roleNames,
            roleType: highestType,
        };
    }
    catch (err) {
        logger_1.loggerRegistry.warn(`Failed to load principal for userId=${userId}: ${err}`);
        // Fallback: minimal principal with just the ID
        return {
            id: userId,
            type: accountType ?? 'user',
            roles: [],
        };
    }
}
