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 } from '@memberjunction/global';
/**
 * Wraps the `MJ: Artifact Permissions` table behind the unified
 * {@link PermissionProviderBase} contract. Artifact permissions are user-only
 * and cover Read / Update / Delete / Share.
 *
 * This provider reads the permission table directly via RunView; it does NOT
 * duplicate the cascade-from-collection logic of the Angular-side
 * `ArtifactPermissionService`. Cascade evaluation belongs in the Sharing Center
 * when it aggregates across both Artifact + Collection domains.
 *
 * `resourceType` is `"Artifacts"`. `resourceId` is the artifact ID.
 */
let ArtifactPermissionProvider = class ArtifactPermissionProvider extends PermissionProviderBase {
    constructor() {
        super(...arguments);
        this.DomainName = 'Artifact Permissions';
        this.Description = 'User-level sharing permissions on conversation artifacts (Read/Update/Delete/Share)';
        this.SupportedGranteeTypes = ['User'];
        this.SupportedActions = ['Read', 'Update', 'Delete', 'Share'];
        this.SupportsDeny = false;
    }
    GetResourceTypes() {
        return ['Artifacts'];
    }
    async CheckPermission(user, _resourceType, resourceId, action) {
        if (!resourceId) {
            return {
                Allowed: false,
                DomainName: this.DomainName,
                Reason: 'Artifact permissions require a specific artifact ID',
            };
        }
        const row = await this.fetchPermissionForUser(resourceId, user.ID);
        const actions = this.toActions(row);
        const allowed = actions.includes(action);
        return {
            Allowed: allowed,
            DomainName: this.DomainName,
            Reason: allowed
                ? `User has ${action} via direct artifact permission`
                : `User has no ${action} permission on artifact '${resourceId}'`,
        };
    }
    async GetEffectivePermissions(user, _resourceType, resourceId) {
        const row = await this.fetchPermissionForUser(resourceId, user.ID);
        if (!row)
            return [];
        const actions = this.toActions(row);
        if (actions.length === 0)
            return [];
        const nameMap = await this.bulkLookupNames('MJ: Artifacts', [resourceId]);
        return [this.buildNormalizedPermission({
                resourceType: 'Artifacts', resourceId, resourceName: nameMap.get(resourceId),
                granteeType: 'User', granteeId: user.ID, granteeName: user.Name, actions,
                sourceRecordId: row.ID,
            })];
    }
    async GetUserResources(user, resourceType) {
        if (resourceType && resourceType !== 'Artifacts')
            return [];
        const rows = await this.fetchRows('MJ: Artifact Permissions', `UserID='${user.ID}'`, ['ID', 'ArtifactID', 'UserID', 'CanRead', 'CanEdit', 'CanDelete', 'CanShare'], 'GetUserResources');
        return this.expandRowsAsGrantee(rows, user, (r) => r.UserID);
    }
    /**
     * ArtifactPermission rows where this user is the grantee AND someone else
     * is the grantor. Excludes rows the user created for themselves.
     */
    async GetPermissionsSharedWithUser(grantee) {
        const rows = await this.fetchRows('MJ: Artifact Permissions', `UserID='${grantee.ID}' AND (SharedByUserID IS NULL OR SharedByUserID <> '${grantee.ID}')`, ['ID', 'ArtifactID', 'UserID', 'User', 'SharedByUserID', 'CanRead', 'CanEdit', 'CanDelete', 'CanShare'], 'GetPermissionsSharedWithUser');
        return this.expandRowsAsGrantee(rows, grantee, (r) => r.UserID);
    }
    /**
     * All ArtifactPermission rows where this user is the SharedByUserID. Unlike
     * Dashboards, Artifacts track the grantor explicitly — there's no implicit
     * "owner without SharedByUserID" case in this table.
     */
    async GetPermissionsGrantedByUser(grantor) {
        const rows = await this.fetchRows('MJ: Artifact Permissions', `SharedByUserID='${grantor.ID}'`, ['ID', 'ArtifactID', 'UserID', 'User', 'SharedByUserID', 'CanRead', 'CanEdit', 'CanDelete', 'CanShare'], 'GetPermissionsGrantedByUser');
        if (rows.length === 0)
            return [];
        const artifactIds = Array.from(new Set(rows.map((r) => r.ArtifactID)));
        const nameMap = await this.bulkLookupNames('MJ: Artifacts', artifactIds);
        const results = [];
        for (const row of rows) {
            const actions = this.toActions(row);
            if (actions.length === 0)
                continue;
            results.push(this.buildNormalizedPermission({
                resourceType: 'Artifacts', resourceId: row.ArtifactID,
                resourceName: nameMap.get(row.ArtifactID),
                granteeType: 'User', granteeId: row.UserID, granteeName: row.User ?? undefined,
                actions, sourceRecordId: row.ID,
            }));
        }
        return results;
    }
    async GetResourcePermissions(resourceType, resourceId) {
        if (resourceType !== 'Artifacts')
            return [];
        const rows = await this.fetchRows('MJ: Artifact Permissions', `ArtifactID='${resourceId}'`, ['ID', 'ArtifactID', 'UserID', 'User', 'CanRead', 'CanEdit', 'CanDelete', 'CanShare'], 'GetResourcePermissions');
        if (rows.length === 0)
            return [];
        const nameMap = await this.bulkLookupNames('MJ: Artifacts', [resourceId]);
        const resourceName = nameMap.get(resourceId);
        const results = [];
        for (const row of rows) {
            const actions = this.toActions(row);
            if (actions.length === 0)
                continue;
            results.push(this.buildNormalizedPermission({
                resourceType: 'Artifacts', resourceId, resourceName,
                granteeType: 'User', granteeId: row.UserID, granteeName: row.User ?? undefined,
                actions, sourceRecordId: row.ID,
            }));
        }
        return results;
    }
    /**
     * Shared tail for `GetUserResources` and `GetPermissionsSharedWithUser` — both
     * emit one row per permission keyed to a specific grantee. Caller passes a
     * function to pluck the grantee ID since the column differs subtly across paths.
     */
    async expandRowsAsGrantee(rows, grantee, _pluckGranteeId) {
        if (rows.length === 0)
            return [];
        const artifactIds = Array.from(new Set(rows.map((r) => r.ArtifactID)));
        const nameMap = await this.bulkLookupNames('MJ: Artifacts', artifactIds);
        const results = [];
        for (const row of rows) {
            const actions = this.toActions(row);
            if (actions.length === 0)
                continue;
            results.push(this.buildNormalizedPermission({
                resourceType: 'Artifacts', resourceId: row.ArtifactID,
                resourceName: nameMap.get(row.ArtifactID),
                granteeType: 'User', granteeId: grantee.ID, granteeName: grantee.Name,
                actions, sourceRecordId: row.ID,
            }));
        }
        return results;
    }
    async fetchPermissionForUser(artifactId, userId) {
        const rows = await this.fetchRows('MJ: Artifact Permissions', `ArtifactID='${artifactId}' AND UserID='${userId}'`, ['ID', 'ArtifactID', 'UserID', 'CanRead', 'CanEdit', 'CanDelete', 'CanShare'], 'fetchPermissionForUser');
        return rows[0] ?? null;
    }
    toActions(row) {
        if (!row)
            return [];
        return this.boolsToActions({
            Read: row.CanRead,
            Update: row.CanEdit,
            Delete: row.CanDelete,
            Share: row.CanShare,
        });
    }
};
ArtifactPermissionProvider = __decorate([
    RegisterClass(PermissionProviderBase, 'MJArtifactPermissionProvider')
], ArtifactPermissionProvider);
export { ArtifactPermissionProvider };
//# sourceMappingURL=ArtifactPermissionProvider.js.map