var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { PermissionProviderBase, } from '@memberjunction/core';
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
/**
 * Wraps `MJ: AI Agent Permissions` behind the unified {@link PermissionProviderBase} contract.
 *
 * AIAgentPermission rows grant either a User (via UserID) or a Role (via RoleID) — never both;
 * the underlying entity enforces this via a table-level validator. Action mapping:
 * - CanView → `Read`
 * - CanRun  → `Execute`
 * - CanEdit → `Update`
 * - CanDelete → `Delete`
 *
 * User+Role grants for the same user are OR-aggregated (any grant of an action suffices).
 *
 * `resourceType` is `"AI Agents"`. `resourceId` is the agent ID.
 */
let AIAgentPermissionProvider = class AIAgentPermissionProvider extends PermissionProviderBase {
    constructor() {
        super(...arguments);
        this.DomainName = 'AI Agent Permissions';
        this.Description = 'User- or role-level permissions on AI agents. Actions: View (Read), Run (Execute), Edit (Update), Delete.';
        this.SupportedGranteeTypes = ['User', 'Role'];
        this.SupportedActions = ['Read', 'Execute', 'Update', 'Delete'];
        this.SupportsDeny = false;
    }
    GetResourceTypes() {
        return ['AI Agents'];
    }
    async CheckPermission(user, _resourceType, resourceId, action) {
        if (!resourceId) {
            return {
                Allowed: false,
                DomainName: this.DomainName,
                Reason: 'AI Agent permissions require a specific agent ID',
            };
        }
        const rows = await this.fetchPermissionsForAgent(resourceId);
        const actions = this.actionsForUser(user, rows);
        const allowed = actions.includes(action);
        return {
            Allowed: allowed,
            DomainName: this.DomainName,
            Reason: allowed
                ? `User has ${action} via user or role grant on agent '${resourceId}'`
                : `User has no ${action} permission on agent '${resourceId}'`,
        };
    }
    async GetEffectivePermissions(user, _resourceType, resourceId) {
        const rows = await this.fetchPermissionsForAgent(resourceId);
        const actions = this.actionsForUser(user, rows);
        if (actions.length === 0)
            return [];
        const nameMap = await this.bulkLookupNames('MJ: AI Agents', [resourceId]);
        return [this.buildNormalizedPermission({
                resourceType: 'AI Agents', resourceId, resourceName: nameMap.get(resourceId),
                granteeType: 'User', granteeId: user.ID, granteeName: user.Name, actions,
            })];
    }
    async GetUserResources(user, resourceType) {
        if (resourceType && resourceType !== 'AI Agents')
            return [];
        const userRoleIds = (user.UserRoles ?? []).map((ur) => ur.RoleID);
        const userFilter = `UserID='${user.ID}'`;
        const roleFilter = userRoleIds.length ? `RoleID IN (${userRoleIds.map((r) => `'${r}'`).join(',')})` : null;
        const combinedFilter = roleFilter ? `(${userFilter}) OR (${roleFilter})` : userFilter;
        const rows = await this.fetchRows('MJ: AI Agent Permissions', combinedFilter, ['ID', 'AgentID', 'RoleID', 'UserID', 'CanView', 'CanRun', 'CanEdit', 'CanDelete'], 'GetUserResources');
        // Group by agent and aggregate actions
        const byAgent = new Map();
        for (const row of rows) {
            const bucket = byAgent.get(row.AgentID) ?? { actions: new Set(), sourceIds: [] };
            for (const a of this.rowActions(row))
                bucket.actions.add(a);
            bucket.sourceIds.push(row.ID);
            byAgent.set(row.AgentID, bucket);
        }
        if (byAgent.size === 0)
            return [];
        const nameMap = await this.bulkLookupNames('MJ: AI Agents', Array.from(byAgent.keys()));
        const results = [];
        for (const [agentId, { actions, sourceIds }] of byAgent) {
            if (actions.size === 0)
                continue;
            results.push(this.buildNormalizedPermission({
                resourceType: 'AI Agents', resourceId: agentId, resourceName: nameMap.get(agentId),
                granteeType: 'User', granteeId: user.ID, granteeName: user.Name,
                actions: Array.from(actions),
                sourceRecordId: sourceIds.length === 1 ? sourceIds[0] : undefined,
            }));
        }
        return results;
    }
    async GetResourcePermissions(resourceType, resourceId) {
        if (resourceType !== 'AI Agents')
            return [];
        const rows = await this.fetchRows('MJ: AI Agent Permissions', `AgentID='${resourceId}'`, ['ID', 'AgentID', 'RoleID', 'UserID', 'Role', 'User', 'CanView', 'CanRun', 'CanEdit', 'CanDelete'], 'GetResourcePermissions');
        if (rows.length === 0)
            return [];
        const nameMap = await this.bulkLookupNames('MJ: AI Agents', [resourceId]);
        const resourceName = nameMap.get(resourceId);
        const results = [];
        for (const row of rows) {
            const actions = this.rowActions(row);
            if (actions.length === 0)
                continue;
            const isUser = row.UserID != null;
            results.push(this.buildNormalizedPermission({
                resourceType: 'AI Agents', resourceId, resourceName,
                granteeType: isUser ? 'User' : 'Role',
                granteeId: isUser ? row.UserID : row.RoleID,
                granteeName: isUser ? row.User ?? undefined : row.Role ?? undefined,
                actions,
                sourceRecordId: row.ID,
            }));
        }
        return results;
    }
    async fetchPermissionsForAgent(agentId) {
        return this.fetchRows('MJ: AI Agent Permissions', `AgentID='${agentId}'`, ['ID', 'AgentID', 'RoleID', 'UserID', 'CanView', 'CanRun', 'CanEdit', 'CanDelete'], 'fetchPermissionsForAgent');
    }
    actionsForUser(user, rows) {
        const set = new Set();
        for (const row of rows) {
            const matches = (row.UserID && UUIDsEqual(row.UserID, user.ID)) ||
                (row.RoleID && user.UserRoles?.some((ur) => UUIDsEqual(ur.RoleID, row.RoleID)));
            if (!matches)
                continue;
            for (const a of this.rowActions(row))
                set.add(a);
        }
        return Array.from(set);
    }
    rowActions(row) {
        return this.boolsToActions({
            Read: row.CanView,
            Execute: row.CanRun,
            Update: row.CanEdit,
            Delete: row.CanDelete,
        });
    }
};
AIAgentPermissionProvider = __decorate([
    RegisterClass(PermissionProviderBase, 'MJAIAgentPermissionProvider')
], AIAgentPermissionProvider);
export { AIAgentPermissionProvider };
//# sourceMappingURL=AIAgentPermissionProvider.js.map