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 DatabaseConfig from "../DatabaseConfig";
import URL from "../../Types/API/URL";
import OnCallDutyPolicyUserOverride from "../../Models/DatabaseModels/OnCallDutyPolicyUserOverride";
import OneUptimeDate from "../../Types/Date";
import BadDataException from "../../Types/Exception/BadDataException";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
import OnCallDutyPolicyFeedService from "./OnCallDutyPolicyFeedService";
import { OnCallDutyPolicyFeedEventType } from "../../Models/DatabaseModels/OnCallDutyPolicyFeed";
import { Gray500 } from "../../Types/BrandColors";
import UserService from "./UserService";
import OnCallDutyPolicyService from "./OnCallDutyPolicyService";
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
export class Service extends DatabaseService {
    constructor() {
        super(OnCallDutyPolicyUserOverride);
    }
    async onBeforeCreate(createBy) {
        var _a, _b;
        if (!createBy.data.startsAt || !createBy.data.endsAt) {
            throw new BadDataException("Start time and end time are required");
        }
        // make sure start time is before end time
        if (OneUptimeDate.isAfter(createBy.data.startsAt, createBy.data.endsAt)) {
            throw new BadDataException("Start time must be before end time");
        }
        // make sure overrideUser and routealertsToUser are not the same
        const overrideUserId = createBy.data.overrideUserId || ((_a = createBy.data.overrideUser) === null || _a === void 0 ? void 0 : _a.id);
        if (!overrideUserId) {
            throw new BadDataException("Override user is required");
        }
        const routeAlertsToUserId = createBy.data.routeAlertsToUserId || ((_b = createBy.data.routeAlertsToUser) === null || _b === void 0 ? void 0 : _b.id);
        if (!routeAlertsToUserId) {
            throw new BadDataException("Route alerts to user is required");
        }
        if (overrideUserId.toString() === routeAlertsToUserId.toString()) {
            throw new BadDataException("Override user and route alerts to user cannot be the same");
        }
        return {
            createBy,
            carryForward: null,
        };
    }
    async onCreateSuccess(_onCreate, createdItem) {
        var _a, _b, _c, _d;
        // add to on call feed.
        const onCallDutyPolicyId = createdItem.onCallDutyPolicyId || ((_a = createdItem.onCallDutyPolicy) === null || _a === void 0 ? void 0 : _a.id);
        const projectId = createdItem.projectId || ((_b = createdItem.project) === null || _b === void 0 ? void 0 : _b.id);
        const overrideUserId = createdItem.overrideUserId || ((_c = createdItem.overrideUser) === null || _c === void 0 ? void 0 : _c.id);
        const routeAlertsToUserId = createdItem.routeAlertsToUserId || ((_d = createdItem.routeAlertsToUser) === null || _d === void 0 ? void 0 : _d.id);
        if (onCallDutyPolicyId &&
            projectId &&
            overrideUserId &&
            routeAlertsToUserId) {
            const onCallPolicyName = await OnCallDutyPolicyService.getOnCallDutyPolicyName({
                onCallDutyPolicyId: onCallDutyPolicyId,
            });
            const overrideUserTimezone = await UserService.getTimezoneForUser(overrideUserId);
            const routeAlertsToUserTimezone = await UserService.getTimezoneForUser(routeAlertsToUserId);
            const timezones = [];
            if (overrideUserTimezone) {
                timezones.push(overrideUserTimezone);
            }
            if (routeAlertsToUserTimezone) {
                timezones.push(routeAlertsToUserTimezone);
            }
            await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
                onCallDutyPolicyId: onCallDutyPolicyId,
                projectId: projectId,
                onCallDutyPolicyFeedEventType: OnCallDutyPolicyFeedEventType.UserOverrideAdded,
                displayColor: Gray500,
                feedInfoInMarkdown: `🔁 Added a User Override Rule for user **${await UserService.getUserMarkdownString({
                    userId: overrideUserId,
                    projectId: projectId,
                })}** for the [On-Call Policy ${onCallPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId, onCallDutyPolicyId)).toString()}). All alerts will be routed to **${await UserService.getUserMarkdownString({
                    userId: routeAlertsToUserId,
                    projectId: projectId,
                })}** from **${OneUptimeDate.getDateAsFormattedStringInMultipleTimezones({
                    date: createdItem.startsAt,
                    timezones: timezones,
                })}**  to **${OneUptimeDate.getDateAsFormattedStringInMultipleTimezones({
                    date: createdItem.endsAt,
                    timezones: timezones,
                })}**. `,
                userId: createdItem.createdByUserId || undefined,
                workspaceNotification: {
                    sendWorkspaceNotification: true,
                    notifyUserId: createdItem.createdByUserId || undefined,
                },
            });
        }
        return createdItem;
    }
    async onBeforeDelete(deleteBy) {
        var _a, _b, _c, _d;
        const itemsToDelete = await this.findBy({
            query: deleteBy.query,
            select: {
                onCallDutyPolicyId: true,
                projectId: true,
                overrideUserId: true,
                routeAlertsToUserId: true,
                startsAt: true,
                endsAt: true,
                createdByUserId: true,
            },
            props: {
                isRoot: true,
            },
            skip: 0,
            limit: LIMIT_PER_PROJECT,
        });
        for (const item of itemsToDelete) {
            const onCallDutyPolicyId = item.onCallDutyPolicyId || ((_a = item.onCallDutyPolicy) === null || _a === void 0 ? void 0 : _a.id);
            const projectId = item.projectId || ((_b = item.project) === null || _b === void 0 ? void 0 : _b.id);
            const overrideUserId = item.overrideUserId || ((_c = item.overrideUser) === null || _c === void 0 ? void 0 : _c.id);
            const routeAlertsToUserId = item.routeAlertsToUserId || ((_d = item.routeAlertsToUser) === null || _d === void 0 ? void 0 : _d.id);
            if (onCallDutyPolicyId &&
                projectId &&
                overrideUserId &&
                routeAlertsToUserId) {
                const onCallPolicyName = await OnCallDutyPolicyService.getOnCallDutyPolicyName({
                    onCallDutyPolicyId: onCallDutyPolicyId,
                });
                const overrideUserTimezone = await UserService.getTimezoneForUser(overrideUserId);
                const routeAlertsToUserTimezone = await UserService.getTimezoneForUser(routeAlertsToUserId);
                const timezones = [];
                if (overrideUserTimezone) {
                    timezones.push(overrideUserTimezone);
                }
                if (routeAlertsToUserTimezone) {
                    timezones.push(routeAlertsToUserTimezone);
                }
                const deleteByUserId = deleteBy.props.userId;
                await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
                    onCallDutyPolicyId: onCallDutyPolicyId,
                    projectId: projectId,
                    onCallDutyPolicyFeedEventType: OnCallDutyPolicyFeedEventType.UserOverrideRemoved,
                    displayColor: Gray500,
                    feedInfoInMarkdown: `❌ Removed a User Override Rule for user **${await UserService.getUserMarkdownString({
                        userId: overrideUserId,
                        projectId: projectId,
                    })}** for the [On-Call Policy ${onCallPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId, onCallDutyPolicyId)).toString()}). All alerts will be routed back to **${await UserService.getUserMarkdownString({
                        userId: overrideUserId,
                        projectId: projectId,
                    })}**`,
                    userId: deleteByUserId || undefined,
                    workspaceNotification: {
                        sendWorkspaceNotification: true,
                        notifyUserId: deleteByUserId || undefined,
                    },
                });
            }
        }
        return {
            deleteBy,
            carryForward: null,
        };
    }
    async getOnCallDutyPolicyUserOverrideLinkInDashboard(data) {
        const projectId = data.projectId;
        const onCallDutyPolicyId = data.onCallDutyPolicyId;
        const onCallDutyPolicyUserOverrideId = data.onCallDutyPolicyUserOverrideId;
        const dashboardUrl = await DatabaseConfig.getDashboardUrl();
        if (!onCallDutyPolicyId) {
            return URL.fromString(dashboardUrl.toString()).addRoute(`/${projectId.toString()}/on-call-duty/user-overrides/${onCallDutyPolicyUserOverrideId.toString()}`);
        }
        return URL.fromString(dashboardUrl.toString()).addRoute(`/${projectId.toString()}/on-call-duty/policies/${onCallDutyPolicyId.toString()}/user-overrides/${onCallDutyPolicyUserOverrideId.toString()}`);
    }
}
__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, "getOnCallDutyPolicyUserOverrideLinkInDashboard", null);
export default new Service();
//# sourceMappingURL=OnCallDutyPolicyUserOverrideService.js.map