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 CompareCriteria from "./CompareCriteria";
import EvaluateOverTime from "./EvaluateOverTime";
import OneUptimeDate from "../../../../Types/Date";
import { CheckOn, FilterType, } from "../../../../Types/Monitor/CriteriaFilter";
import logger from "../../Logger";
import CaptureSpan from "../../Telemetry/CaptureSpan";
export default class ServerMonitorCriteria {
    static async isMonitorInstanceCriteriaFilterMet(input) {
        // Server Monitoring Checks
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
        let threshold = input.criteriaFilter.value;
        let overTimeValue = undefined;
        if (input.criteriaFilter.evaluateOverTime &&
            input.criteriaFilter.evaluateOverTimeOptions) {
            try {
                overTimeValue = await EvaluateOverTime.getValueOverTime({
                    projectId: input.dataToProcess.projectId,
                    monitorId: input.dataToProcess.monitorId,
                    evaluateOverTimeOptions: input.criteriaFilter.evaluateOverTimeOptions,
                    metricType: input.criteriaFilter.checkOn,
                    miscData: input.criteriaFilter.serverMonitorOptions,
                });
                if (Array.isArray(overTimeValue) && overTimeValue.length === 0) {
                    overTimeValue = undefined;
                }
            }
            catch (err) {
                logger.error(`Error in getting over time value for ${input.criteriaFilter.checkOn}`);
                logger.error(err);
                overTimeValue = undefined;
            }
        }
        const lastCheckTime = input.dataToProcess
            .requestReceivedAt;
        const timeNow = input.dataToProcess.timeNow ||
            OneUptimeDate.getCurrentDate();
        const differenceInMinutes = OneUptimeDate.getDifferenceInMinutes(lastCheckTime, timeNow);
        let offlineIfNotCheckedInMinutes = 3;
        // check evaluate  over time.
        if (input.criteriaFilter.evaluateOverTime &&
            input.criteriaFilter.evaluateOverTimeOptions) {
            offlineIfNotCheckedInMinutes =
                input.criteriaFilter.evaluateOverTimeOptions.timeValueInMinutes || 3;
        }
        logger.debug("Server Monitor Criteria Filter");
        logger.debug(`Monitor ID: ${input.dataToProcess.monitorId}`);
        logger.debug(`Check On: ${input.criteriaFilter.checkOn}`);
        logger.debug(`Difference in Minutes: ${differenceInMinutes}`);
        logger.debug(`Offline if not checked in minutes: ${offlineIfNotCheckedInMinutes}`);
        const normalizeDiskPath = (value) => {
            let normalized = (value || "").trim().toLowerCase();
            if (normalized === "/") {
                return normalized;
            }
            normalized = normalized.replace(/\\/g, "/");
            normalized = normalized.replace(/\/+$/g, "");
            if (normalized === "") {
                return "/";
            }
            return normalized;
        };
        if (input.criteriaFilter.checkOn === CheckOn.IsOnline &&
            differenceInMinutes >= offlineIfNotCheckedInMinutes) {
            const currentIsOnline = overTimeValue || false; // false because no request receieved in the last 2 minutes
            logger.debug(`Current Is Online: ${currentIsOnline}`);
            const criteria = CompareCriteria.compareCriteriaBoolean({
                value: currentIsOnline,
                criteriaFilter: input.criteriaFilter,
            });
            logger.debug(`Criteria: ${criteria}`);
            return criteria;
        }
        if (input.criteriaFilter.checkOn === CheckOn.IsOnline &&
            differenceInMinutes < offlineIfNotCheckedInMinutes) {
            const currentIsOnline = overTimeValue || true; // true because request receieved in the last 2 minutes
            logger.debug(`Current Is Online: ${currentIsOnline}`);
            const criteria = CompareCriteria.compareCriteriaBoolean({
                value: currentIsOnline,
                criteriaFilter: input.criteriaFilter,
            });
            logger.debug(`Criteria: ${criteria}`);
            return criteria;
        }
        if (input.criteriaFilter.checkOn === CheckOn.CPUUsagePercent &&
            !input.dataToProcess.onlyCheckRequestReceivedAt) {
            threshold = CompareCriteria.convertToNumber(threshold);
            const currentCpuPercent = overTimeValue ||
                ((_a = input.dataToProcess
                    .basicInfrastructureMetrics) === null || _a === void 0 ? void 0 : _a.cpuMetrics.percentUsed) ||
                0;
            return CompareCriteria.compareCriteriaNumbers({
                value: currentCpuPercent,
                threshold: threshold,
                criteriaFilter: input.criteriaFilter,
            });
        }
        if (input.criteriaFilter.checkOn === CheckOn.MemoryUsagePercent &&
            !input.dataToProcess.onlyCheckRequestReceivedAt) {
            threshold = CompareCriteria.convertToNumber(threshold);
            const memoryPercent = overTimeValue ||
                ((_b = input.dataToProcess
                    .basicInfrastructureMetrics) === null || _b === void 0 ? void 0 : _b.memoryMetrics.percentUsed) ||
                0;
            return CompareCriteria.compareCriteriaNumbers({
                value: memoryPercent,
                threshold: threshold,
                criteriaFilter: input.criteriaFilter,
            });
        }
        if (input.criteriaFilter.checkOn === CheckOn.DiskUsagePercent &&
            !input.dataToProcess.onlyCheckRequestReceivedAt) {
            threshold = CompareCriteria.convertToNumber(threshold);
            const diskPath = ((_c = input.criteriaFilter.serverMonitorOptions) === null || _c === void 0 ? void 0 : _c.diskPath) || "/";
            const normalizedDiskPath = normalizeDiskPath(diskPath);
            const diskMetric = (_d = input.dataToProcess.basicInfrastructureMetrics) === null || _d === void 0 ? void 0 : _d.diskMetrics.find((item) => {
                return normalizeDiskPath(item.diskPath) === normalizedDiskPath;
            });
            const diskUsagePercent = (_f = (_e = diskMetric === null || diskMetric === void 0 ? void 0 : diskMetric.percentUsed) !== null && _e !== void 0 ? _e : diskMetric === null || diskMetric === void 0 ? void 0 : diskMetric.percentFree) !== null && _f !== void 0 ? _f : 0;
            return CompareCriteria.compareCriteriaNumbers({
                value: diskUsagePercent,
                threshold: threshold,
                criteriaFilter: input.criteriaFilter,
            });
        }
        if (!input.dataToProcess
            .onlyCheckRequestReceivedAt &&
            (input.criteriaFilter.checkOn === CheckOn.LoadAverage1Min ||
                input.criteriaFilter.checkOn === CheckOn.LoadAverage5Min ||
                input.criteriaFilter.checkOn === CheckOn.LoadAverage15Min)) {
            threshold = CompareCriteria.convertToNumber(threshold);
            const loadMetrics = (_g = input.dataToProcess
                .basicInfrastructureMetrics) === null || _g === void 0 ? void 0 : _g.loadMetrics;
            let currentLoad = undefined;
            if (input.criteriaFilter.checkOn === CheckOn.LoadAverage1Min) {
                currentLoad = loadMetrics === null || loadMetrics === void 0 ? void 0 : loadMetrics.load1;
            }
            else if (input.criteriaFilter.checkOn === CheckOn.LoadAverage5Min) {
                currentLoad = loadMetrics === null || loadMetrics === void 0 ? void 0 : loadMetrics.load5;
            }
            else if (input.criteriaFilter.checkOn === CheckOn.LoadAverage15Min) {
                currentLoad = loadMetrics === null || loadMetrics === void 0 ? void 0 : loadMetrics.load15;
            }
            const value = overTimeValue || currentLoad || 0;
            return CompareCriteria.compareCriteriaNumbers({
                value: value,
                threshold: threshold,
                criteriaFilter: input.criteriaFilter,
            });
        }
        if (input.criteriaFilter.checkOn === CheckOn.SwapUsagePercent &&
            !input.dataToProcess.onlyCheckRequestReceivedAt) {
            threshold = CompareCriteria.convertToNumber(threshold);
            const swapPercent = overTimeValue ||
                ((_j = (_h = input.dataToProcess
                    .basicInfrastructureMetrics) === null || _h === void 0 ? void 0 : _h.memoryMetrics) === null || _j === void 0 ? void 0 : _j.swapPercentUsed) ||
                0;
            return CompareCriteria.compareCriteriaNumbers({
                value: swapPercent,
                threshold: threshold,
                criteriaFilter: input.criteriaFilter,
            });
        }
        if (input.criteriaFilter.checkOn === CheckOn.CPUIoWaitPercent &&
            !input.dataToProcess.onlyCheckRequestReceivedAt) {
            threshold = CompareCriteria.convertToNumber(threshold);
            const ioWaitPercent = overTimeValue ||
                ((_l = (_k = input.dataToProcess
                    .basicInfrastructureMetrics) === null || _k === void 0 ? void 0 : _k.cpuMetrics) === null || _l === void 0 ? void 0 : _l.timeIoWaitPercent) ||
                0;
            return CompareCriteria.compareCriteriaNumbers({
                value: ioWaitPercent,
                threshold: threshold,
                criteriaFilter: input.criteriaFilter,
            });
        }
        if (input.criteriaFilter.checkOn === CheckOn.ServerProcessName &&
            threshold &&
            !input.dataToProcess.onlyCheckRequestReceivedAt) {
            const thresholdProcessName = threshold
                .toString()
                .trim()
                .toLowerCase();
            if (input.criteriaFilter.filterType === FilterType.IsExecuting) {
                const processNames = ((_o = (_m = input.dataToProcess) === null || _m === void 0 ? void 0 : _m.processes) === null || _o === void 0 ? void 0 : _o.map((item) => {
                    return item.name.trim().toLowerCase();
                })) || [];
                if (processNames.includes(thresholdProcessName)) {
                    return `Process ${threshold} is executing.`;
                }
                return null;
            }
            if (input.criteriaFilter.filterType === FilterType.IsNotExecuting) {
                const processNames = ((_q = (_p = input.dataToProcess) === null || _p === void 0 ? void 0 : _p.processes) === null || _q === void 0 ? void 0 : _q.map((item) => {
                    return item.name.trim().toLowerCase();
                })) || [];
                if (!processNames.includes(thresholdProcessName)) {
                    return `Process ${threshold} is not executing.`;
                }
                return null;
            }
        }
        if (input.criteriaFilter.checkOn === CheckOn.ServerProcessPID &&
            threshold &&
            !input.dataToProcess.onlyCheckRequestReceivedAt) {
            const thresholdProcessPID = threshold
                .toString()
                .trim()
                .toLowerCase();
            if (input.criteriaFilter.filterType === FilterType.IsExecuting) {
                const processPIDs = ((_s = (_r = input.dataToProcess) === null || _r === void 0 ? void 0 : _r.processes) === null || _s === void 0 ? void 0 : _s.map((item) => {
                    return item.pid.toString().trim().toLowerCase();
                })) || [];
                if (processPIDs.includes(thresholdProcessPID)) {
                    return `Process with PID ${threshold} is executing.`;
                }
                return null;
            }
            if (input.criteriaFilter.filterType === FilterType.IsNotExecuting) {
                const processPIDs = ((_u = (_t = input.dataToProcess) === null || _t === void 0 ? void 0 : _t.processes) === null || _u === void 0 ? void 0 : _u.map((item) => {
                    return item.pid.toString().trim().toLowerCase();
                })) || [];
                if (!processPIDs.includes(thresholdProcessPID)) {
                    return `Process with PID ${threshold} is not executing.`;
                }
                return null;
            }
            return null;
        }
        if (input.criteriaFilter.checkOn === CheckOn.ServerProcessCommand &&
            threshold &&
            !input.dataToProcess.onlyCheckRequestReceivedAt) {
            const thresholdProcessCommand = threshold
                .toString()
                .trim()
                .toLowerCase();
            if (input.criteriaFilter.filterType === FilterType.IsExecuting) {
                const processCommands = ((_w = (_v = input.dataToProcess) === null || _v === void 0 ? void 0 : _v.processes) === null || _w === void 0 ? void 0 : _w.map((item) => {
                    return item.command.trim().toLowerCase();
                })) || [];
                if (processCommands.includes(thresholdProcessCommand)) {
                    return `Process with command ${threshold} is executing.`;
                }
                return null;
            }
            if (input.criteriaFilter.filterType === FilterType.IsNotExecuting) {
                const processCommands = ((_y = (_x = input.dataToProcess) === null || _x === void 0 ? void 0 : _x.processes) === null || _y === void 0 ? void 0 : _y.map((item) => {
                    return item.command.trim().toLowerCase();
                })) || [];
                if (!processCommands.includes(thresholdProcessCommand)) {
                    return `Process with command ${threshold} is not executing.`;
                }
                return null;
            }
            return null;
        }
        return null;
    }
}
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], ServerMonitorCriteria, "isMonitorInstanceCriteriaFilterMet", null);
//# sourceMappingURL=ServerMonitorCriteria.js.map