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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { IsBillingEnabled } from "../EnvironmentConfig";
import QueryHelper from "../Types/Database/QueryHelper";
import DatabaseService from "./DatabaseService";
import OnCallDutyPolicyEscalationRuleScheduleService from "./OnCallDutyPolicyEscalationRuleScheduleService";
import OnCallDutyPolicyEscalationRuleTeamService from "./OnCallDutyPolicyEscalationRuleTeamService";
import OnCallDutyPolicyEscalationRuleUserService from "./OnCallDutyPolicyEscalationRuleUserService";
import OnCallDutyPolicyExecutionLogService from "./OnCallDutyPolicyExecutionLogService";
import OnCallDutyPolicyExecutionLogTimelineService from "./OnCallDutyPolicyExecutionLogTimelineService";
import OnCallDutyPolicyScheduleService from "./OnCallDutyPolicyScheduleService";
import TeamMemberService from "./TeamMemberService";
import UserNotificationRuleService from "./UserNotificationRuleService";
import SortOrder from "../../Types/BaseDatabase/SortOrder";
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
import OneUptimeDate from "../../Types/Date";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import OnCallDutyExecutionLogTimelineStatus from "../../Types/OnCallDutyPolicy/OnCalDutyExecutionLogTimelineStatus";
import UserNotificationEventType from "../../Types/UserNotification/UserNotificationEventType";
import Model from "../../Models/DatabaseModels/OnCallDutyPolicyEscalationRule";
import OnCallDutyPolicyEscalationRuleSchedule from "../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule";
import OnCallDutyPolicyEscalationRuleTeam from "../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam";
import OnCallDutyPolicyEscalationRuleUser from "../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser";
import OnCallDutyPolicyExecutionLogTimeline from "../../Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline";
import logger from "../Utils/Logger";
import OnCallDutyPolicyUserOverrideService from "./OnCallDutyPolicyUserOverrideService";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
export class Service extends DatabaseService {
    async getRouteAlertToUserId(data) {
        logger.debug(`Getting route alert to user id for userId: ${data.userId.toString()}`, {
            projectId: data.projectId.toString(),
            userId: data.userId.toString(),
        });
        const currentDate = OneUptimeDate.getCurrentDate();
        const alertRoutedTo = await OnCallDutyPolicyUserOverrideService.findBy({
            query: {
                overrideUserId: data.userId,
                onCallDutyPolicyId: QueryHelper.equalToOrNull(data.onCallDutyPolicyId), // find global overrides as well. If this is null, then it will find global overrides.
                projectId: data.projectId,
                startsAt: QueryHelper.lessThanEqualTo(currentDate),
                endsAt: QueryHelper.greaterThanEqualTo(currentDate),
            },
            props: {
                isRoot: true,
            },
            limit: LIMIT_PER_PROJECT,
            skip: 0,
            select: {
                routeAlertsToUserId: true,
                onCallDutyPolicyId: true,
            },
        });
        logger.debug(`Found alert routed to: ${JSON.stringify(alertRoutedTo)}`, {
            projectId: data.projectId.toString(),
            userId: data.userId.toString(),
        });
        // local override takes precedence over global override.
        const localOverride = alertRoutedTo.find((item) => {
            var _a;
            return (((_a = item.onCallDutyPolicyId) === null || _a === void 0 ? void 0 : _a.toString()) ===
                data.onCallDutyPolicyId.toString());
        });
        if (localOverride && localOverride.routeAlertsToUserId) {
            logger.debug(`Route alert to user id found: ${localOverride.routeAlertsToUserId.toString()}`, {
                projectId: data.projectId.toString(),
                userId: data.userId.toString(),
            });
            return localOverride.routeAlertsToUserId;
        }
        const globalOverride = alertRoutedTo.find((item) => {
            return !item.onCallDutyPolicyId;
        });
        if (globalOverride && globalOverride.routeAlertsToUserId) {
            logger.debug(`Route alert to user id found: ${globalOverride.routeAlertsToUserId.toString()}`, {
                projectId: data.projectId.toString(),
                userId: data.userId.toString(),
            });
            return globalOverride.routeAlertsToUserId;
        }
        return null;
    }
    async startRuleExecution(ruleId, options) {
        logger.debug(`Starting rule execution for ruleId: ${ruleId.toString()}`, {
            projectId: options.projectId.toString(),
            onCallDutyPolicyEscalationRuleId: ruleId.toString(),
        });
        const rule = await this.findOneById({
            id: ruleId,
            select: {
                _id: true,
                order: true,
                escalateAfterInMinutes: true,
            },
            props: {
                isRoot: true,
            },
        });
        if (!rule) {
            throw new BadDataException(`On-Call Duty Policy Escalation Rule with id ${ruleId.toString()} not found`);
        }
        logger.debug(`Found rule: ${JSON.stringify(rule)}`, {
            projectId: options.projectId.toString(),
            onCallDutyPolicyEscalationRuleId: ruleId.toString(),
        });
        await OnCallDutyPolicyExecutionLogService.updateOneById({
            id: options.onCallPolicyExecutionLogId,
            data: {
                lastEscalationRuleExecutedAt: OneUptimeDate.getCurrentDate(),
                lastExecutedEscalationRuleId: ruleId,
                lastExecutedEscalationRuleOrder: rule.order,
                executeNextEscalationRuleInMinutes: rule.escalateAfterInMinutes || 0,
            },
            props: {
                isRoot: true,
            },
        });
        logger.debug(`Updated execution log for ruleId: ${ruleId.toString()}`, {
            projectId: options.projectId.toString(),
            onCallDutyPolicyEscalationRuleId: ruleId.toString(),
        });
        const getNewLog = () => {
            const log = new OnCallDutyPolicyExecutionLogTimeline();
            log.projectId = options.projectId;
            log.onCallDutyPolicyExecutionLogId = options.onCallPolicyExecutionLogId;
            log.onCallDutyPolicyId = options.onCallPolicyId;
            log.onCallDutyPolicyEscalationRuleId = ruleId;
            log.userNotificationEventType = options.userNotificationEventType;
            if (options.triggeredByIncidentId) {
                log.triggeredByIncidentId = options.triggeredByIncidentId;
            }
            if (options.triggeredByAlertId) {
                log.triggeredByAlertId = options.triggeredByAlertId;
            }
            if (options.triggeredByAlertEpisodeId) {
                log.triggeredByAlertEpisodeId = options.triggeredByAlertEpisodeId;
            }
            if (options.triggeredByIncidentEpisodeId) {
                log.triggeredByIncidentEpisodeId =
                    options.triggeredByIncidentEpisodeId;
            }
            return log;
        };
        if (UserNotificationEventType.IncidentCreated ===
            options.userNotificationEventType &&
            !options.triggeredByIncidentId) {
            throw new BadDataException("triggeredByIncidentId is required when userNotificationEventType is IncidentCreated");
        }
        if (UserNotificationEventType.AlertCreated ===
            options.userNotificationEventType &&
            !options.triggeredByAlertId) {
            throw new BadDataException("triggeredByAlertId is required when userNotificationEventType is AlertCreated");
        }
        if (UserNotificationEventType.AlertEpisodeCreated ===
            options.userNotificationEventType &&
            !options.triggeredByAlertEpisodeId) {
            throw new BadDataException("triggeredByAlertEpisodeId is required when userNotificationEventType is AlertEpisodeCreated");
        }
        if (UserNotificationEventType.IncidentEpisodeCreated ===
            options.userNotificationEventType &&
            !options.triggeredByIncidentEpisodeId) {
            throw new BadDataException("triggeredByIncidentEpisodeId is required when userNotificationEventType is IncidentEpisodeCreated");
        }
        const usersInRule = await OnCallDutyPolicyEscalationRuleUserService.findBy({
            query: {
                onCallDutyPolicyEscalationRuleId: ruleId,
            },
            props: {
                isRoot: true,
            },
            skip: 0,
            limit: LIMIT_PER_PROJECT,
            select: {
                userId: true,
            },
        });
        logger.debug(`Found users in rule: ${JSON.stringify(usersInRule)}`, {
            projectId: options.projectId.toString(),
            onCallDutyPolicyEscalationRuleId: ruleId.toString(),
        });
        const teamsInRule = await OnCallDutyPolicyEscalationRuleTeamService.findBy({
            query: {
                onCallDutyPolicyEscalationRuleId: ruleId,
            },
            props: {
                isRoot: true,
            },
            skip: 0,
            limit: LIMIT_PER_PROJECT,
            select: {
                teamId: true,
            },
        });
        logger.debug(`Found teams in rule: ${JSON.stringify(teamsInRule)}`, {
            projectId: options.projectId.toString(),
            onCallDutyPolicyEscalationRuleId: ruleId.toString(),
        });
        const schedulesInRule = await OnCallDutyPolicyEscalationRuleScheduleService.findBy({
            query: {
                onCallDutyPolicyEscalationRuleId: ruleId,
            },
            props: {
                isRoot: true,
            },
            skip: 0,
            limit: LIMIT_PER_PROJECT,
            select: {
                onCallDutyPolicyScheduleId: true,
            },
        });
        logger.debug(`Found schedules in rule: ${JSON.stringify(schedulesInRule)}`, {
            projectId: options.projectId.toString(),
            onCallDutyPolicyEscalationRuleId: ruleId.toString(),
        });
        const startUserNotificationRuleExecution = async (userId, teamId, scheduleId) => {
            // This is where user is notified.
            // get route alert to user id.
            let routeAlertToUserId = null;
            if (options.onCallPolicyId) {
                routeAlertToUserId = await this.getRouteAlertToUserId({
                    userId,
                    onCallDutyPolicyId: options.onCallPolicyId,
                    projectId: options.projectId,
                });
            }
            const alertSentToUserId = routeAlertToUserId || userId;
            logger.debug(`Starting notification rule execution for userId: ${alertSentToUserId.toString()}`, {
                projectId: options.projectId.toString(),
                onCallDutyPolicyEscalationRuleId: ruleId.toString(),
                userId: alertSentToUserId.toString(),
            });
            let log = getNewLog();
            log.statusMessage = "Sending notification to user.";
            log.status = OnCallDutyExecutionLogTimelineStatus.Executing;
            log.alertSentToUserId = alertSentToUserId;
            if (routeAlertToUserId) {
                log.overridedByUserId = userId;
            }
            if (teamId) {
                log.userBelongsToTeamId = teamId;
            }
            if (scheduleId) {
                log.onCallDutyScheduleId = scheduleId;
            }
            log = await OnCallDutyPolicyExecutionLogTimelineService.create({
                data: log,
                props: {
                    isRoot: true,
                },
            });
            await UserNotificationRuleService.startUserNotificationRulesExecution(alertSentToUserId, {
                userNotificationEventType: options.userNotificationEventType,
                triggeredByIncidentId: options.triggeredByIncidentId || undefined,
                triggeredByAlertId: options.triggeredByAlertId || undefined,
                triggeredByAlertEpisodeId: options.triggeredByAlertEpisodeId || undefined,
                triggeredByIncidentEpisodeId: options.triggeredByIncidentEpisodeId || undefined,
                onCallPolicyExecutionLogId: options.onCallPolicyExecutionLogId,
                onCallPolicyId: options.onCallPolicyId,
                onCallPolicyEscalationRuleId: ruleId,
                userBelongsToTeamId: teamId || undefined,
                onCallDutyPolicyExecutionLogTimelineId: log.id,
                projectId: options.projectId,
                onCallScheduleId: scheduleId || undefined,
                overridedByUserId: routeAlertToUserId ? userId : undefined,
            });
        };
        const uniqueUserIds = [];
        for (const teamInRule of teamsInRule) {
            const usersInTeam = await TeamMemberService.getUsersInTeam(teamInRule.teamId);
            for (const user of usersInTeam) {
                if (!uniqueUserIds.find((userId) => {
                    var _a;
                    return ((_a = user.id) === null || _a === void 0 ? void 0 : _a.toString()) === userId.toString();
                })) {
                    uniqueUserIds.push(user.id);
                    await startUserNotificationRuleExecution(user.id, teamInRule.teamId, null);
                }
                else {
                    const log = getNewLog();
                    log.statusMessage =
                        "Skipped because notification sent to this user already.";
                    log.status = OnCallDutyExecutionLogTimelineStatus.Skipped;
                    log.alertSentToUserId = user.id;
                    log.userBelongsToTeamId = teamInRule.teamId;
                    await OnCallDutyPolicyExecutionLogTimelineService.create({
                        data: log,
                        props: {
                            isRoot: true,
                        },
                    });
                }
            }
        }
        for (const userRule of usersInRule) {
            if (!uniqueUserIds.find((userId) => {
                var _a;
                return ((_a = userRule.userId) === null || _a === void 0 ? void 0 : _a.toString()) === userId.toString();
            })) {
                uniqueUserIds.push(userRule.userId);
                await startUserNotificationRuleExecution(userRule.userId, null, null);
            }
            else {
                const log = getNewLog();
                log.statusMessage =
                    "Skipped because notification sent to this user already.";
                log.status = OnCallDutyExecutionLogTimelineStatus.Skipped;
                log.alertSentToUserId = userRule.userId;
                await OnCallDutyPolicyExecutionLogTimelineService.create({
                    data: log,
                    props: {
                        isRoot: true,
                    },
                });
            }
        }
        for (const scheduleRule of schedulesInRule) {
            const userIdInSchedule = await OnCallDutyPolicyScheduleService.getCurrentUserIdInSchedule(scheduleRule.onCallDutyPolicyScheduleId, { onCallDutyPolicyId: options.onCallPolicyId });
            if (!userIdInSchedule) {
                const log = getNewLog();
                log.statusMessage =
                    "Skipped because no active users are found in this schedule.";
                log.status = OnCallDutyExecutionLogTimelineStatus.Skipped;
                log.onCallDutyScheduleId = scheduleRule.onCallDutyPolicyScheduleId;
                await OnCallDutyPolicyExecutionLogTimelineService.create({
                    data: log,
                    props: {
                        isRoot: true,
                    },
                });
                continue;
            }
            if (!uniqueUserIds.find((userId) => {
                return (userIdInSchedule === null || userIdInSchedule === void 0 ? void 0 : userIdInSchedule.toString()) === userId.toString();
            })) {
                uniqueUserIds.push(userIdInSchedule);
                await startUserNotificationRuleExecution(userIdInSchedule, null, scheduleRule.onCallDutyPolicyScheduleId);
            }
            else {
                const log = getNewLog();
                log.statusMessage =
                    "Skipped because notification sent to this user already.";
                log.status = OnCallDutyExecutionLogTimelineStatus.Skipped;
                log.alertSentToUserId = userIdInSchedule;
                log.onCallDutyScheduleId = scheduleRule.onCallDutyPolicyScheduleId;
                await OnCallDutyPolicyExecutionLogTimelineService.create({
                    data: log,
                    props: {
                        isRoot: true,
                    },
                });
            }
        }
        if (uniqueUserIds.length === 0) {
            const log = getNewLog();
            log.statusMessage = "Skipped because no users in this rule.";
            log.status = OnCallDutyExecutionLogTimelineStatus.Skipped;
            await OnCallDutyPolicyExecutionLogTimelineService.create({
                data: log,
                props: {
                    isRoot: true,
                },
            });
        }
        logger.debug(`Completed rule execution for ruleId: ${ruleId.toString()}`, {
            projectId: options.projectId.toString(),
            onCallDutyPolicyEscalationRuleId: ruleId.toString(),
        });
    }
    constructor() {
        super(Model);
    }
    async onCreateSuccess(onCreate, createdItem) {
        if (!createdItem.projectId) {
            throw new BadDataException("projectId is required");
        }
        if (!createdItem.id) {
            throw new BadDataException("id is required");
        }
        // add people in escalation rule.
        if (onCreate.createBy.miscDataProps &&
            (onCreate.createBy.miscDataProps["teams"] ||
                onCreate.createBy.miscDataProps["users"] ||
                onCreate.createBy.miscDataProps["onCallSchedules"])) {
            await this.addUsersTeamsAndSchedules(createdItem.projectId, createdItem.id, createdItem.onCallDutyPolicyId, onCreate.createBy.miscDataProps["users"] || [], onCreate.createBy.miscDataProps["teams"] || [], onCreate.createBy.miscDataProps["onCallSchedules"] || [], onCreate.createBy.props);
        }
        return createdItem;
    }
    async addUsersTeamsAndSchedules(projectId, escalationRuleId, onCallDutyPolicyId, usersIds, teamIds, onCallScheduleIds, props) {
        for (const userId of usersIds) {
            await this.addUser(projectId, escalationRuleId, onCallDutyPolicyId, userId, props);
        }
        for (const teamId of teamIds) {
            await this.addTeam(projectId, escalationRuleId, onCallDutyPolicyId, teamId, props);
        }
        for (const scheduleId of onCallScheduleIds) {
            await this.addOnCallSchedules(projectId, escalationRuleId, onCallDutyPolicyId, scheduleId, props);
        }
    }
    async addTeam(projectId, escalationRuleId, onCallDutyPolicyId, teamId, props) {
        const teamInRule = new OnCallDutyPolicyEscalationRuleTeam();
        teamInRule.projectId = projectId;
        teamInRule.onCallDutyPolicyId = onCallDutyPolicyId;
        teamInRule.onCallDutyPolicyEscalationRuleId = escalationRuleId;
        teamInRule.teamId = teamId;
        if (props.userId) {
            teamInRule.createdByUserId = props.userId;
        }
        await OnCallDutyPolicyEscalationRuleTeamService.create({
            data: teamInRule,
            props,
        });
    }
    async addOnCallSchedules(projectId, escalationRuleId, onCallDutyPolicyId, onCallScheduleId, props) {
        const scheduleInRule = new OnCallDutyPolicyEscalationRuleSchedule();
        scheduleInRule.projectId = projectId;
        scheduleInRule.onCallDutyPolicyId = onCallDutyPolicyId;
        scheduleInRule.onCallDutyPolicyEscalationRuleId = escalationRuleId;
        scheduleInRule.onCallDutyPolicyScheduleId = onCallScheduleId;
        if (props.userId) {
            scheduleInRule.createdByUserId = props.userId;
        }
        await OnCallDutyPolicyEscalationRuleScheduleService.create({
            data: scheduleInRule,
            props,
        });
    }
    async addUser(projectId, escalationRuleId, onCallDutyPolicyId, userId, props) {
        const userInRule = new OnCallDutyPolicyEscalationRuleUser();
        userInRule.projectId = projectId;
        userInRule.onCallDutyPolicyId = onCallDutyPolicyId;
        userInRule.onCallDutyPolicyEscalationRuleId = escalationRuleId;
        userInRule.userId = userId;
        if (props.userId) {
            userInRule.createdByUserId = props.userId;
        }
        await OnCallDutyPolicyEscalationRuleUserService.create({
            data: userInRule,
            props,
        });
    }
    async onBeforeCreate(createBy) {
        var _a;
        if (IsBillingEnabled && createBy.props.currentPlan === PlanType.Free) {
            // then check no of policies and if it is more than one, return error
            const count = await this.countBy({
                query: {
                    projectId: createBy.data.projectId,
                    onCallDutyPolicyId: createBy.data.onCallDutyPolicyId ||
                        ((_a = createBy.data.onCallDutyPolicy) === null || _a === void 0 ? void 0 : _a._id),
                },
                props: {
                    isRoot: true,
                },
            });
            if (count.toNumber() >= 1) {
                throw new BadDataException("You can only create one escalation rule in free plan.");
            }
        }
        if (!createBy.data.onCallDutyPolicyId) {
            throw new BadDataException("Status Page Resource onCallDutyPolicyId is required");
        }
        if (!createBy.data.order) {
            const query = {
                onCallDutyPolicyId: createBy.data.onCallDutyPolicyId,
            };
            const count = await this.countBy({
                query: query,
                props: {
                    isRoot: true,
                },
            });
            createBy.data.order = count.toNumber() + 1;
        }
        await this.rearrangeOrder(createBy.data.order, createBy.data.onCallDutyPolicyId, true);
        return {
            createBy: createBy,
            carryForward: null,
        };
    }
    async onBeforeDelete(deleteBy) {
        if (!deleteBy.query._id && !deleteBy.props.isRoot) {
            throw new BadDataException("_id should be present when deleting status page resource. Please try the delete with objectId");
        }
        let resource = null;
        if (!deleteBy.props.isRoot) {
            resource = await this.findOneBy({
                query: deleteBy.query,
                props: {
                    isRoot: true,
                },
                select: {
                    order: true,
                    onCallDutyPolicyId: true,
                    projectId: true,
                },
            });
            if (!resource) {
                throw new BadDataException("OnCallDutyPolicyEscalationRule with this id not found");
            }
            // delete users in escalation rule, teams in escalation rule and schedules in escalation rule.
            await OnCallDutyPolicyEscalationRuleScheduleService.deleteBy({
                query: {
                    onCallDutyPolicyEscalationRuleId: resource.id,
                    projectId: resource.projectId,
                },
                limit: LIMIT_PER_PROJECT,
                skip: 0,
                props: {
                    userId: deleteBy.props.userId,
                    isRoot: true,
                },
            });
            // delete users in escalation rule.
            await OnCallDutyPolicyEscalationRuleUserService.deleteBy({
                query: {
                    onCallDutyPolicyEscalationRuleId: resource.id,
                    projectId: resource.projectId,
                },
                limit: LIMIT_PER_PROJECT,
                skip: 0,
                props: {
                    userId: deleteBy.props.userId,
                    isRoot: true,
                },
            });
            // delete teams in escalation rule.
            await OnCallDutyPolicyEscalationRuleTeamService.deleteBy({
                query: {
                    onCallDutyPolicyEscalationRuleId: resource.id,
                    projectId: resource.projectId,
                },
                limit: LIMIT_PER_PROJECT,
                skip: 0,
                props: {
                    userId: deleteBy.props.userId,
                    isRoot: true,
                },
            });
        }
        return {
            deleteBy,
            carryForward: resource,
        };
    }
    async onDeleteSuccess(onDelete, _itemIdsBeforeDelete) {
        const deleteBy = onDelete.deleteBy;
        const resource = onDelete.carryForward;
        if (!deleteBy.props.isRoot && resource) {
            if (resource && resource.order && resource.onCallDutyPolicyId) {
                await this.rearrangeOrder(resource.order, resource.onCallDutyPolicyId, false);
            }
        }
        return {
            deleteBy: deleteBy,
            carryForward: null,
        };
    }
    async onBeforeUpdate(updateBy) {
        if (updateBy.data.order && !updateBy.props.isRoot && updateBy.query._id) {
            const resource = await this.findOneBy({
                query: {
                    _id: updateBy.query._id,
                },
                props: {
                    isRoot: true,
                },
                select: {
                    order: true,
                    onCallDutyPolicyId: true,
                    _id: true,
                },
            });
            const currentOrder = resource === null || resource === void 0 ? void 0 : resource.order;
            const newOrder = updateBy.data.order;
            const resources = await this.findBy({
                query: {
                    onCallDutyPolicyId: resource === null || resource === void 0 ? void 0 : resource.onCallDutyPolicyId,
                },
                limit: LIMIT_MAX,
                skip: 0,
                props: {
                    isRoot: true,
                },
                select: {
                    order: true,
                    onCallDutyPolicyId: true,
                    _id: true,
                },
            });
            if (currentOrder > newOrder) {
                // moving up.
                for (const resource of resources) {
                    if (resource.order >= newOrder && resource.order < currentOrder) {
                        // increment order.
                        await this.updateOneBy({
                            query: {
                                _id: resource._id,
                            },
                            data: {
                                order: resource.order + 1,
                            },
                            props: {
                                isRoot: true,
                            },
                        });
                    }
                }
            }
            if (newOrder > currentOrder) {
                // moving down.
                for (const resource of resources) {
                    if (resource.order <= newOrder) {
                        // increment order.
                        await this.updateOneBy({
                            query: {
                                _id: resource._id,
                            },
                            data: {
                                order: resource.order - 1,
                            },
                            props: {
                                isRoot: true,
                            },
                        });
                    }
                }
            }
        }
        return { updateBy, carryForward: null };
    }
    async rearrangeOrder(currentOrder, onCallDutyPolicyId, increaseOrder = true) {
        // get status page resource with this order.
        const resources = await this.findBy({
            query: {
                order: QueryHelper.greaterThanEqualTo(currentOrder),
                onCallDutyPolicyId: onCallDutyPolicyId,
            },
            limit: LIMIT_MAX,
            skip: 0,
            props: {
                isRoot: true,
            },
            select: {
                _id: true,
                order: true,
            },
            sort: {
                order: SortOrder.Ascending,
            },
        });
        let newOrder = currentOrder;
        for (const resource of resources) {
            if (increaseOrder) {
                newOrder = resource.order + 1;
            }
            else {
                newOrder = resource.order - 1;
            }
            await this.updateOneBy({
                query: {
                    _id: resource._id,
                },
                data: {
                    order: newOrder,
                },
                props: {
                    isRoot: true,
                },
            });
        }
    }
}
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "getRouteAlertToUserId", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID, Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "startRuleExecution", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Model]),
    __metadata("design:returntype", Promise)
], Service.prototype, "onCreateSuccess", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID,
        ObjectID,
        ObjectID,
        Array,
        Array,
        Array, Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "addUsersTeamsAndSchedules", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID,
        ObjectID,
        ObjectID,
        ObjectID, Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "addTeam", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID,
        ObjectID,
        ObjectID,
        ObjectID, Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "addOnCallSchedules", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID,
        ObjectID,
        ObjectID,
        ObjectID, Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "addUser", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "onBeforeCreate", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "onBeforeDelete", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Array]),
    __metadata("design:returntype", Promise)
], Service.prototype, "onDeleteSuccess", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "onBeforeUpdate", null);
export default new Service();
//# sourceMappingURL=OnCallDutyPolicyEscalationRuleService.js.map