"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveAccess = resolveAccess;
exports.resolveUserFromApiKey = resolveUserFromApiKey;
exports.resolveUserFromBearer = resolveUserFromBearer;
exports.canRead = canRead;
exports.canWrite = canWrite;
const crypto_1 = __importDefault(require("crypto"));
const jwt_1 = require("../lib/jwt");
/**
 * Resolve access level for a user on a specific graph.
 *
 * Resolution chain (first match wins):
 *   graph.access[userId] → project.access[userId] → workspace.access[userId]
 *   → server.access[userId] → server.defaultAccess
 */
function resolveAccess(userId, graphName, projectConfig, serverConfig, workspaceConfig) {
    if (!userId)
        return serverConfig.defaultAccess;
    // 1. Graph-level
    const graphAccess = projectConfig.graphConfigs[graphName].access?.[userId];
    if (graphAccess)
        return graphAccess;
    // 2. Project-level
    const projectAccess = projectConfig.access?.[userId];
    if (projectAccess)
        return projectAccess;
    // 3. Workspace-level
    if (workspaceConfig) {
        const wsAccess = workspaceConfig.access?.[userId];
        if (wsAccess)
            return wsAccess;
    }
    // 4. Server-level
    const serverAccess = serverConfig.access?.[userId];
    if (serverAccess)
        return serverAccess;
    // 5. Default
    return serverConfig.defaultAccess;
}
/**
 * Look up a user by API key.
 * Returns { userId, user } or undefined if not found.
 */
function resolveUserFromApiKey(apiKey, users) {
    const keyBuf = Buffer.from(apiKey);
    for (const [userId, user] of Object.entries(users)) {
        const userKeyBuf = Buffer.from(user.apiKey);
        if (keyBuf.length === userKeyBuf.length && crypto_1.default.timingSafeEqual(keyBuf, userKeyBuf)) {
            return { userId, user };
        }
    }
    return undefined;
}
/**
 * Resolve a user from a Bearer token — tries OAuth JWT first, then falls back to API key.
 * Used by MCP HTTP handler to accept both OAuth tokens and legacy API keys.
 */
function resolveUserFromBearer(token, users, jwtSecret) {
    if (jwtSecret) {
        const payload = (0, jwt_1.verifyToken)(token, jwtSecret);
        if (payload?.type === 'oauth_access') {
            const user = users[payload.userId];
            if (user)
                return { userId: payload.userId, user };
        }
    }
    return resolveUserFromApiKey(token, users);
}
/**
 * Check if an access level allows read operations.
 */
function canRead(level) {
    return level === 'r' || level === 'rw';
}
/**
 * Check if an access level allows write operations.
 */
function canWrite(level) {
    return level === 'rw';
}
