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 DatabaseService from "./DatabaseService";
import OnCallDutyPolicyEscalationRuleService from "./OnCallDutyPolicyEscalationRuleService";
import OnCallDutyPolicyStatus from "../../Types/OnCallDutyPolicy/OnCallDutyPolicyStatus";
import UserNotificationEventType from "../../Types/UserNotification/UserNotificationEventType";
import Model from "../../Models/DatabaseModels/OnCallDutyPolicyExecutionLog";
import { IsBillingEnabled } from "../EnvironmentConfig";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
import IncidentFeedService from "./IncidentFeedService";
import { IncidentFeedEventType } from "../../Models/DatabaseModels/IncidentFeed";
import { Blue500, Green500, Red500, Yellow500 } from "../../Types/BrandColors";
import OnCallDutyPolicyService from "./OnCallDutyPolicyService";
import AlertFeedService from "./AlertFeedService";
import { AlertFeedEventType } from "../../Models/DatabaseModels/AlertFeed";
import AlertEpisodeFeedService from "./AlertEpisodeFeedService";
import { AlertEpisodeFeedEventType } from "../../Models/DatabaseModels/AlertEpisodeFeed";
import IncidentEpisodeFeedService from "./IncidentEpisodeFeedService";
import { IncidentEpisodeFeedEventType } from "../../Models/DatabaseModels/IncidentEpisodeFeed";
import BadDataException from "../../Types/Exception/BadDataException";
import IncidentService from "./IncidentService";
import AlertService from "./AlertService";
import AlertEpisodeService from "./AlertEpisodeService";
import IncidentEpisodeService from "./IncidentEpisodeService";
export class Service extends DatabaseService {
    constructor() {
        super(Model);
        if (IsBillingEnabled) {
            this.hardDeleteItemsOlderThanInDays("createdAt", 30);
        }
    }
    async onBeforeCreate(createBy) {
        if (!createBy.data.status) {
            createBy.data.status = OnCallDutyPolicyStatus.Scheduled;
        }
        if (!createBy.data.statusMessage) {
            createBy.data.statusMessage = "Scheduled.";
        }
        if (createBy.props.userId) {
            createBy.data.triggeredByUserId = createBy.props.userId;
        }
        createBy.data.onCallPolicyExecutionRepeatCount = 1;
        return { createBy, carryForward: null };
    }
    async onCreateSuccess(_onCreate, createdItem) {
        if (createdItem.triggeredByIncidentId ||
            createdItem.triggeredByAlertId ||
            createdItem.triggeredByAlertEpisodeId ||
            createdItem.triggeredByIncidentEpisodeId) {
            const onCallPolicy = await OnCallDutyPolicyService.findOneById({
                id: createdItem.onCallDutyPolicyId,
                select: {
                    _id: true,
                    projectId: true,
                    name: true,
                },
                props: {
                    isRoot: true,
                },
            });
            if (onCallPolicy && onCallPolicy.id) {
                let incidentOrAlertLink = "";
                if (createdItem.triggeredByIncidentId) {
                    const projectId = createdItem.projectId;
                    const incidentId = createdItem.triggeredByIncidentId;
                    const incidentNumberResult = await IncidentService.getIncidentNumber({
                        incidentId: incidentId,
                    });
                    const incidentNumberDisplay = incidentNumberResult.numberWithPrefix ||
                        "#" + incidentNumberResult.number;
                    incidentOrAlertLink = `[Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId, incidentId)).toString()})`;
                }
                if (createdItem.triggeredByAlertId) {
                    const alertNumberResult = await AlertService.getAlertNumber({
                        alertId: createdItem.triggeredByAlertId,
                    });
                    incidentOrAlertLink = `[Alert ${alertNumberResult.numberWithPrefix || "#" + alertNumberResult.number}](${(await AlertService.getAlertLinkInDashboard(createdItem.projectId, createdItem.triggeredByAlertId)).toString()})`;
                }
                if (createdItem.triggeredByAlertEpisodeId) {
                    const alertEpisodeNumberResult = await AlertEpisodeService.getEpisodeNumber({
                        episodeId: createdItem.triggeredByAlertEpisodeId,
                    });
                    incidentOrAlertLink = `[Alert Episode ${alertEpisodeNumberResult.numberWithPrefix || "#" + alertEpisodeNumberResult.number}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(createdItem.projectId, createdItem.triggeredByAlertEpisodeId)).toString()})`;
                }
                if (createdItem.triggeredByIncidentEpisodeId) {
                    const incidentEpisodeNumberResult = await IncidentEpisodeService.getEpisodeNumber({
                        episodeId: createdItem.triggeredByIncidentEpisodeId,
                    });
                    incidentOrAlertLink = `[Incident Episode ${incidentEpisodeNumberResult.numberWithPrefix || "#" + incidentEpisodeNumberResult.number}](${(await IncidentEpisodeService.getEpisodeLinkInDashboard(createdItem.projectId, createdItem.triggeredByIncidentEpisodeId)).toString()})`;
                }
                const feedInfoInMarkdown = `**📞 On Call Policy Started Executing:** On Call Policy **${onCallPolicy.name}** started executing for ${incidentOrAlertLink}. Users on call on this policy will now be notified.`;
                if (onCallPolicy &&
                    onCallPolicy.id &&
                    createdItem.triggeredByIncidentId) {
                    await IncidentFeedService.createIncidentFeedItem({
                        incidentId: createdItem.triggeredByIncidentId,
                        projectId: createdItem.projectId,
                        incidentFeedEventType: IncidentFeedEventType.OnCallPolicy,
                        displayColor: Yellow500,
                        feedInfoInMarkdown: feedInfoInMarkdown,
                        workspaceNotification: {
                            sendWorkspaceNotification: true,
                        },
                    });
                }
                if (onCallPolicy && onCallPolicy.id && createdItem.triggeredByAlertId) {
                    await AlertFeedService.createAlertFeedItem({
                        alertId: createdItem.triggeredByAlertId,
                        projectId: createdItem.projectId,
                        alertFeedEventType: AlertFeedEventType.OnCallPolicy,
                        displayColor: Yellow500,
                        feedInfoInMarkdown: feedInfoInMarkdown,
                    });
                }
                if (onCallPolicy &&
                    onCallPolicy.id &&
                    createdItem.triggeredByAlertEpisodeId) {
                    await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
                        alertEpisodeId: createdItem.triggeredByAlertEpisodeId,
                        projectId: createdItem.projectId,
                        alertEpisodeFeedEventType: AlertEpisodeFeedEventType.OnCallPolicy,
                        displayColor: Yellow500,
                        feedInfoInMarkdown: feedInfoInMarkdown,
                    });
                }
                if (onCallPolicy &&
                    onCallPolicy.id &&
                    createdItem.triggeredByIncidentEpisodeId) {
                    await IncidentEpisodeFeedService.createIncidentEpisodeFeedItem({
                        incidentEpisodeId: createdItem.triggeredByIncidentEpisodeId,
                        projectId: createdItem.projectId,
                        incidentEpisodeFeedEventType: IncidentEpisodeFeedEventType.OnCallPolicy,
                        displayColor: Yellow500,
                        feedInfoInMarkdown: feedInfoInMarkdown,
                    });
                }
            }
        }
        // get execution rules in this policy adn execute the first rule.
        const executionRule = await OnCallDutyPolicyEscalationRuleService.findOneBy({
            query: {
                projectId: createdItem.projectId,
                onCallDutyPolicyId: createdItem.onCallDutyPolicyId,
                order: 1,
            },
            props: {
                isRoot: true,
            },
            select: {
                _id: true,
            },
        });
        if (executionRule) {
            await this.updateOneById({
                id: createdItem.id,
                data: {
                    status: OnCallDutyPolicyStatus.Started,
                    statusMessage: "Execution started...",
                },
                props: {
                    isRoot: true,
                },
            });
            let userNotificationEventType = null;
            if (createdItem.triggeredByIncidentId) {
                userNotificationEventType = UserNotificationEventType.IncidentCreated;
            }
            if (createdItem.triggeredByAlertId) {
                userNotificationEventType = UserNotificationEventType.AlertCreated;
            }
            if (createdItem.triggeredByAlertEpisodeId) {
                userNotificationEventType =
                    UserNotificationEventType.AlertEpisodeCreated;
            }
            if (createdItem.triggeredByIncidentEpisodeId) {
                userNotificationEventType =
                    UserNotificationEventType.IncidentEpisodeCreated;
            }
            if (!userNotificationEventType) {
                throw new BadDataException("Invalid userNotificationEventType");
            }
            await OnCallDutyPolicyEscalationRuleService.startRuleExecution(executionRule.id, {
                projectId: createdItem.projectId,
                triggeredByIncidentId: createdItem.triggeredByIncidentId,
                triggeredByAlertId: createdItem.triggeredByAlertId,
                triggeredByAlertEpisodeId: createdItem.triggeredByAlertEpisodeId,
                triggeredByIncidentEpisodeId: createdItem.triggeredByIncidentEpisodeId,
                userNotificationEventType: userNotificationEventType,
                onCallPolicyExecutionLogId: createdItem.id,
                onCallPolicyId: createdItem.onCallDutyPolicyId,
            });
            await this.updateOneById({
                id: createdItem.id,
                data: {
                    status: OnCallDutyPolicyStatus.Executing,
                    statusMessage: "First escalation rule executed...",
                },
                props: {
                    isRoot: true,
                },
            });
        }
        else {
            await this.updateOneById({
                id: createdItem.id,
                data: {
                    status: OnCallDutyPolicyStatus.Error,
                    statusMessage: "No Escalation Rules in Policy. Please add escalation rules to this policy.",
                },
                props: {
                    isRoot: true,
                },
            });
        }
        return createdItem;
    }
    getDisplayColorByStatus(status) {
        switch (status) {
            case OnCallDutyPolicyStatus.Scheduled:
                return Blue500;
            case OnCallDutyPolicyStatus.Started:
                return Yellow500;
            case OnCallDutyPolicyStatus.Executing:
                return Yellow500;
            case OnCallDutyPolicyStatus.Completed:
                return Green500;
            case OnCallDutyPolicyStatus.Error:
                return Red500;
            default:
                return Blue500;
        }
    }
    getEmojiByStatus(status) {
        switch (status) {
            case OnCallDutyPolicyStatus.Scheduled:
                return "📅";
            case OnCallDutyPolicyStatus.Started:
                return "🚀";
            case OnCallDutyPolicyStatus.Executing:
                return "▶️";
            case OnCallDutyPolicyStatus.Completed:
                return "🏁";
            case OnCallDutyPolicyStatus.Error:
                return "❌";
            default:
                return "📅";
        }
    }
    async onUpdateSuccess(onUpdate, _updatedItemIds) {
        var _a;
        // if status is updtaed then check if this on-call is related to the incident, if yes, then add to incident feed.
        if (onUpdate.updateBy.data.status && onUpdate.updateBy.query._id) {
            const id = onUpdate.updateBy.query._id;
            const onCalldutyPolicyExecutionLog = await this.findOneById({
                id: id,
                select: {
                    _id: true,
                    projectId: true,
                    onCallDutyPolicyId: true,
                    status: true,
                    statusMessage: true,
                    triggeredByIncidentId: true,
                    triggeredByAlertId: true,
                    triggeredByAlertEpisodeId: true,
                    triggeredByIncidentEpisodeId: true,
                },
                props: {
                    isRoot: true,
                },
            });
            if (onCalldutyPolicyExecutionLog &&
                (onCalldutyPolicyExecutionLog.triggeredByIncidentId ||
                    onCalldutyPolicyExecutionLog.triggeredByAlertId ||
                    onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId ||
                    onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId)) {
                const onCallPolicy = await OnCallDutyPolicyService.findOneById({
                    id: onCalldutyPolicyExecutionLog.onCallDutyPolicyId,
                    select: {
                        _id: true,
                        projectId: true,
                        name: true,
                    },
                    props: {
                        isRoot: true,
                    },
                });
                if (onCallPolicy && onCallPolicy.id) {
                    const moreInformationInMarkdown = `**Status:** ${onCalldutyPolicyExecutionLog.status}

**Message:** ${onCalldutyPolicyExecutionLog.statusMessage}`;
                    let incidentOrAlertLink = "";
                    if (onCalldutyPolicyExecutionLog.triggeredByIncidentId) {
                        const projectId = onCalldutyPolicyExecutionLog.projectId;
                        const incidentId = onCalldutyPolicyExecutionLog.triggeredByIncidentId;
                        const incidentNumberResult = await IncidentService.getIncidentNumber({
                            incidentId: incidentId,
                        });
                        const incidentNumberDisplay = incidentNumberResult.numberWithPrefix ||
                            "#" + incidentNumberResult.number;
                        incidentOrAlertLink = `[Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId, incidentId)).toString()})`;
                    }
                    if (onCalldutyPolicyExecutionLog.triggeredByAlertId) {
                        const alertNumberResult = await AlertService.getAlertNumber({
                            alertId: onCalldutyPolicyExecutionLog.triggeredByAlertId,
                        });
                        incidentOrAlertLink = `[Alert ${alertNumberResult.numberWithPrefix || "#" + alertNumberResult.number}](${(await AlertService.getAlertLinkInDashboard(onCalldutyPolicyExecutionLog.projectId, onCalldutyPolicyExecutionLog.triggeredByAlertId)).toString()})`;
                    }
                    if (onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId) {
                        const alertEpisodeNumberResult = await AlertEpisodeService.getEpisodeNumber({
                            episodeId: onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId,
                        });
                        incidentOrAlertLink = `[Alert Episode ${alertEpisodeNumberResult.numberWithPrefix || "#" + alertEpisodeNumberResult.number}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(onCalldutyPolicyExecutionLog.projectId, onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId)).toString()})`;
                    }
                    if (onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId) {
                        const incidentEpisodeNumberResult = await IncidentEpisodeService.getEpisodeNumber({
                            episodeId: onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId,
                        });
                        incidentOrAlertLink = `[Incident Episode ${incidentEpisodeNumberResult.numberWithPrefix || "#" + incidentEpisodeNumberResult.number}](${(await IncidentEpisodeService.getEpisodeLinkInDashboard(onCalldutyPolicyExecutionLog.projectId, onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId)).toString()})`;
                    }
                    const feedInfoInMarkdown = `**${this.getEmojiByStatus(onCalldutyPolicyExecutionLog.status)} On Call Policy Status Updated for ${incidentOrAlertLink}:**

 On-call policy **[${(_a = onCallPolicy.name) === null || _a === void 0 ? void 0 : _a.toString()}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(onCallPolicy.projectId, onCallPolicy.id)).toString()})** status updated to **${onCalldutyPolicyExecutionLog.status}**`;
                    if (onCalldutyPolicyExecutionLog.triggeredByIncidentId) {
                        await IncidentFeedService.createIncidentFeedItem({
                            incidentId: onCalldutyPolicyExecutionLog.triggeredByIncidentId,
                            projectId: onCalldutyPolicyExecutionLog.projectId,
                            incidentFeedEventType: IncidentFeedEventType.OnCallPolicy,
                            displayColor: onCalldutyPolicyExecutionLog.status
                                ? this.getDisplayColorByStatus(onCalldutyPolicyExecutionLog.status)
                                : Blue500,
                            moreInformationInMarkdown: moreInformationInMarkdown,
                            feedInfoInMarkdown: feedInfoInMarkdown,
                            workspaceNotification: {
                                sendWorkspaceNotification: true,
                            },
                        });
                    }
                    if (onCalldutyPolicyExecutionLog.triggeredByAlertId) {
                        await AlertFeedService.createAlertFeedItem({
                            alertId: onCalldutyPolicyExecutionLog.triggeredByAlertId,
                            projectId: onCalldutyPolicyExecutionLog.projectId,
                            alertFeedEventType: AlertFeedEventType.OnCallPolicy,
                            displayColor: onCalldutyPolicyExecutionLog.status
                                ? this.getDisplayColorByStatus(onCalldutyPolicyExecutionLog.status)
                                : Blue500,
                            moreInformationInMarkdown: moreInformationInMarkdown,
                            feedInfoInMarkdown: feedInfoInMarkdown,
                        });
                    }
                    if (onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId) {
                        await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
                            alertEpisodeId: onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId,
                            projectId: onCalldutyPolicyExecutionLog.projectId,
                            alertEpisodeFeedEventType: AlertEpisodeFeedEventType.OnCallPolicy,
                            displayColor: onCalldutyPolicyExecutionLog.status
                                ? this.getDisplayColorByStatus(onCalldutyPolicyExecutionLog.status)
                                : Blue500,
                            moreInformationInMarkdown: moreInformationInMarkdown,
                            feedInfoInMarkdown: feedInfoInMarkdown,
                        });
                    }
                    if (onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId) {
                        await IncidentEpisodeFeedService.createIncidentEpisodeFeedItem({
                            incidentEpisodeId: onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId,
                            projectId: onCalldutyPolicyExecutionLog.projectId,
                            incidentEpisodeFeedEventType: IncidentEpisodeFeedEventType.OnCallPolicy,
                            displayColor: onCalldutyPolicyExecutionLog.status
                                ? this.getDisplayColorByStatus(onCalldutyPolicyExecutionLog.status)
                                : Blue500,
                            moreInformationInMarkdown: moreInformationInMarkdown,
                            feedInfoInMarkdown: feedInfoInMarkdown,
                        });
                    }
                }
            }
        }
        return onUpdate;
    }
}
__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, Model]),
    __metadata("design:returntype", Promise)
], Service.prototype, "onCreateSuccess", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Array]),
    __metadata("design:returntype", Promise)
], Service.prototype, "onUpdateSuccess", null);
export default new Service();
//# sourceMappingURL=OnCallDutyPolicyExecutionLogService.js.map