import Permission from "../../../Types/Permission";
import Text from "../../../Types/Text";
import { combineWithPrivacyClause } from "../PrivacyFilterUtil";
import { Raw } from "typeorm";
/*
 * Project owners and admins, plus root/master-admin contexts, see all
 * private alerts. Other users only see private alerts they own
 * (directly via AlertOwnerUser, or transitively through AlertOwnerTeam
 * + TeamMember).
 */
export function shouldBypassAlertPrivacy(props) {
    var _a;
    if (props.isRoot || props.isMasterAdmin) {
        return true;
    }
    if (props.tenantId && props.userTenantAccessPermission) {
        const tenantPerm = props.userTenantAccessPermission[props.tenantId.toString()];
        if ((_a = tenantPerm === null || tenantPerm === void 0 ? void 0 : tenantPerm.permissions) === null || _a === void 0 ? void 0 : _a.some((p) => {
            return (p.permission === Permission.ProjectOwner ||
                p.permission === Permission.ProjectAdmin);
        })) {
            return true;
        }
    }
    return false;
}
/*
 * Raw clause to apply on Alert.isPrivate. Lets non-private rows through
 * unconditionally, and private rows only when the current user is an owner
 * (directly, or via team membership). Returns undefined when the caller
 * should bypass the filter entirely.
 */
export function getAlertSelfPrivacyRaw(props) {
    if (shouldBypassAlertPrivacy(props)) {
        return undefined;
    }
    if (!props.userId) {
        return Raw((alias) => {
            return `(${alias} IS NULL OR ${alias} = FALSE)`;
        });
    }
    const uidRid = "uidPriv_" + Text.generateRandomText(10);
    return Raw((alias) => {
        return (`(${alias} IS NULL OR ${alias} = FALSE OR ` +
            `"Alert"."_id" IN (SELECT aou."alertId" FROM "AlertOwnerUser" aou WHERE aou."userId" = :${uidRid} AND aou."deletedAt" IS NULL) OR ` +
            `"Alert"."_id" IN (SELECT aot."alertId" FROM "AlertOwnerTeam" aot INNER JOIN "TeamMember" tm ON tm."teamId" = aot."teamId" WHERE tm."userId" = :${uidRid} AND tm."deletedAt" IS NULL AND aot."deletedAt" IS NULL))`);
    }, {
        [uidRid]: props.userId.toString(),
    });
}
/*
 * Raw clause to apply on a child table's alertId column. Only rows whose
 * parent Alert the user is allowed to see pass. Returns undefined when the
 * caller should bypass the filter entirely.
 */
export function getAlertRelatedRecordPrivacyRaw(props) {
    if (shouldBypassAlertPrivacy(props)) {
        return undefined;
    }
    if (!props.userId) {
        return Raw((alias) => {
            return `(${alias} IN (SELECT a."_id" FROM "Alert" a WHERE a."deletedAt" IS NULL AND (a."isPrivate" IS NULL OR a."isPrivate" = FALSE)))`;
        });
    }
    const uidRid = "uidRel_" + Text.generateRandomText(10);
    return Raw((alias) => {
        return (`(${alias} IN (SELECT a."_id" FROM "Alert" a WHERE a."deletedAt" IS NULL AND (` +
            `a."isPrivate" IS NULL OR a."isPrivate" = FALSE OR ` +
            `a."_id" IN (SELECT aou."alertId" FROM "AlertOwnerUser" aou WHERE aou."userId" = :${uidRid} AND aou."deletedAt" IS NULL) OR ` +
            `a."_id" IN (SELECT aot."alertId" FROM "AlertOwnerTeam" aot INNER JOIN "TeamMember" tm ON tm."teamId" = aot."teamId" WHERE tm."userId" = :${uidRid} AND tm."deletedAt" IS NULL AND aot."deletedAt" IS NULL))))`);
    }, {
        [uidRid]: props.userId.toString(),
    });
}
export function applyAlertSelfPrivacyFilter(query, props) {
    const rawClause = getAlertSelfPrivacyRaw(props);
    if (!rawClause) {
        return query;
    }
    if (!query) {
        return { isPrivate: rawClause };
    }
    query.isPrivate = combineWithPrivacyClause(query.isPrivate, rawClause);
    return query;
}
export function applyAlertRelatedRecordPrivacyFilter(query, props) {
    const rawClause = getAlertRelatedRecordPrivacyRaw(props);
    if (!rawClause) {
        return query;
    }
    if (!query) {
        return { alertId: rawClause };
    }
    query.alertId = combineWithPrivacyClause(query.alertId, rawClause);
    return query;
}
//# sourceMappingURL=AlertPrivacyFilter.js.map