import { Green } from "../../Types/BrandColors";
import MonitorStatus from "../../Models/DatabaseModels/MonitorStatus";
import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
import UptimeUtil from "../Uptime/UptimeUtil";
export default class StatusPageResourceUptimeUtil {
    static getWorstMonitorStatus(data) {
        let worstStatus = new MonitorStatus();
        worstStatus.name = "Operational";
        worstStatus.color = Green;
        for (const status of data.monitorStatuses) {
            if ((worstStatus &&
                worstStatus.priority &&
                status.priority &&
                status.priority > worstStatus.priority) ||
                !worstStatus ||
                !worstStatus.priority) {
                worstStatus = status;
            }
        }
        return worstStatus;
    }
    static getMonitorStatusTimelineForResource(data) {
        return [...data.monitorStatusTimelines].filter((timeline) => {
            // check monitor if first.
            var _a, _b, _c;
            if (data.statusPageResource.monitorId) {
                return (((_a = timeline.monitorId) === null || _a === void 0 ? void 0 : _a.toString()) ===
                    ((_b = data.statusPageResource.monitorId) === null || _b === void 0 ? void 0 : _b.toString()));
            }
            if (data.statusPageResource.monitorGroupId) {
                const monitorsInThisGroup = data.monitorsInGroup[((_c = data.statusPageResource.monitorGroupId) === null || _c === void 0 ? void 0 : _c.toString()) || ""];
                if (!monitorsInThisGroup) {
                    return false;
                }
                return monitorsInThisGroup.find((monitorId) => {
                    var _a;
                    return monitorId.toString() === ((_a = timeline.monitorId) === null || _a === void 0 ? void 0 : _a.toString());
                });
            }
            return false;
        });
    }
    static getCurrentStatusPageGroupStatus(data) {
        let currentStatus = new MonitorStatus();
        currentStatus.name = "Operational";
        currentStatus.color = Green;
        const resourcesInGroup = this.getResourcesInStatusPageGroup({
            statusPageGroup: data.statusPageGroup,
            statusPageResources: data.statusPageResources,
        });
        for (const resource of resourcesInGroup) {
            let currentMonitorStatus = undefined;
            if (resource.monitor) {
                currentMonitorStatus = data.monitorStatuses.find((status) => {
                    var _a, _b, _c;
                    return (((_a = status._id) === null || _a === void 0 ? void 0 : _a.toString()) ===
                        ((_c = (_b = resource.monitor) === null || _b === void 0 ? void 0 : _b.currentMonitorStatusId) === null || _c === void 0 ? void 0 : _c.toString()));
                });
            }
            if (resource.monitorGroupId) {
                currentMonitorStatus = data.monitorStatuses.find((status) => {
                    var _a, _b, _c;
                    return (((_a = status._id) === null || _a === void 0 ? void 0 : _a.toString()) ===
                        ((_c = data.monitorGroupCurrentStatuses[((_b = resource.monitorGroupId) === null || _b === void 0 ? void 0 : _b.toString()) || ""]) === null || _c === void 0 ? void 0 : _c.toString()));
                });
            }
            if (!currentMonitorStatus) {
                currentMonitorStatus = currentStatus;
            }
            if ((currentStatus &&
                currentStatus.priority &&
                (currentMonitorStatus === null || currentMonitorStatus === void 0 ? void 0 : currentMonitorStatus.priority) &&
                (currentMonitorStatus === null || currentMonitorStatus === void 0 ? void 0 : currentMonitorStatus.priority) > currentStatus.priority) ||
                !currentStatus ||
                !currentStatus.priority) {
                currentStatus = currentMonitorStatus;
            }
        }
        return currentStatus;
    }
    static calculateUptimePercentOfResource(data) {
        if (!data.statusPageResource.showUptimePercent) {
            return null;
        }
        const monitorStatusTimelines = this.getMonitorStatusTimelineForResource({
            statusPageResource: data.statusPageResource,
            monitorStatusTimelines: data.monitorStatusTimelines,
            monitorsInGroup: data.monitorsInGroup,
        });
        const downtimeMonitorStatuses = (data === null || data === void 0 ? void 0 : data.downtimeMonitorStatuses) || [];
        const uptimePercent = UptimeUtil.calculateUptimePercentage(monitorStatusTimelines, data.precision, downtimeMonitorStatuses);
        return uptimePercent;
    }
    static calculateAvgUptimePercentOfStatusPageGroup(data) {
        if (!data.statusPageGroup.showUptimePercent) {
            return null;
        }
        const resourcesInGroup = this.getResourcesInStatusPageGroup({
            statusPageGroup: data.statusPageGroup,
            statusPageResources: data.statusPageResources,
        });
        if (resourcesInGroup.length === 0) {
            return null; // no resources in group.
        }
        const uptimePercentPerResource = [];
        for (const resource of resourcesInGroup) {
            const calculateUptimePercentOfResource = this.calculateUptimePercentOfResource({
                statusPageResource: resource,
                monitorStatusTimelines: data.monitorStatusTimelines,
                precision: data.precision,
                downtimeMonitorStatuses: data.downtimeMonitorStatuses,
                monitorsInGroup: data.monitorsInGroup,
            });
            if (calculateUptimePercentOfResource !== null) {
                uptimePercentPerResource.push(calculateUptimePercentOfResource);
            }
        }
        // calculate avg
        if (uptimePercentPerResource.length === 0) {
            return null;
        }
        const averageUptimePercentage = uptimePercentPerResource.reduce((a, b) => {
            return a + b;
        }) / uptimePercentPerResource.length;
        // if the current status is operational then show uptime Percent.
        let precision = UptimePrecision.ONE_DECIMAL;
        if (data.statusPageGroup.uptimePercentPrecision) {
            precision = data.statusPageGroup.uptimePercentPrecision;
        }
        return UptimeUtil.roundToPrecision({
            number: averageUptimePercentage,
            precision: precision,
        });
    }
    static getResourcesWithoutStatusPageGroup(data) {
        return data.statusPageResources.filter((resource) => {
            return !resource.statusPageGroupId;
        });
    }
    static getResourcesInStatusPageGroup(data) {
        return data.statusPageResources.filter((resource) => {
            var _a, _b;
            return (((_a = resource.statusPageGroupId) === null || _a === void 0 ? void 0 : _a.toString()) ===
                ((_b = data.statusPageGroup._id) === null || _b === void 0 ? void 0 : _b.toString()));
        });
    }
    static calculateAvgUptimePercentageOfAllResources(data) {
        const showUptimePercentage = Boolean(data.statusPageResources.find((item) => {
            return item.showUptimePercent || item.showStatusHistoryChart;
        }));
        if (!showUptimePercentage) {
            return null;
        }
        const allUptimePercent = [];
        // calculate for groups first.
        for (const group of data.resourceGroups) {
            const calculateAvgUptimePercentOfStatusPageGroup = this.calculateAvgUptimePercentOfStatusPageGroup({
                statusPageGroup: group,
                monitorStatusTimelines: data.monitorStatusTimelines,
                precision: data.precision,
                downtimeMonitorStatuses: data.downtimeMonitorStatuses,
                statusPageResources: data.statusPageResources,
                monitorsInGroup: data.monitorsInGroup,
            });
            if (calculateAvgUptimePercentOfStatusPageGroup !== null) {
                allUptimePercent.push(calculateAvgUptimePercentOfStatusPageGroup);
            }
        }
        // now fetch resources without group.
        const resourcesWithoutGroup = this.getResourcesWithoutStatusPageGroup({
            statusPageResources: data.statusPageResources,
        });
        for (const resource of resourcesWithoutGroup) {
            const calculateUptimePercentOfResource = this.calculateUptimePercentOfResource({
                statusPageResource: resource,
                monitorStatusTimelines: data.monitorStatusTimelines,
                precision: data.precision,
                downtimeMonitorStatuses: data.downtimeMonitorStatuses,
                monitorsInGroup: data.monitorsInGroup,
            });
            if (calculateUptimePercentOfResource !== null) {
                allUptimePercent.push(calculateUptimePercentOfResource);
            }
        }
        // calculate avg
        if (allUptimePercent.length === 0) {
            return null;
        }
        const averageUptimePercentage = allUptimePercent.reduce((a, b) => {
            return a + b;
        }) / allUptimePercent.length;
        return UptimeUtil.roundToPrecision({
            number: averageUptimePercentage,
            precision: data.precision,
        });
    }
}
//# sourceMappingURL=ResourceUptime.js.map