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 logger from "../../../Utils/Logger";
import { CheckOn, EvaluateOverTimeType, FilterType, } from "../../../../Types/Monitor/CriteriaFilter";
import Typeof from "../../../../Types/Typeof";
import CaptureSpan from "../../Telemetry/CaptureSpan";
export default class CompareCriteria {
    static greaterThan(data) {
        if (Array.isArray(data.value)) {
            if (data.evaluationType === EvaluateOverTimeType.AnyValue) {
                return data.value.some((value) => {
                    return value > data.threshold;
                });
            }
            return data.value.every((value) => {
                return value > data.threshold;
            });
        }
        return data.value > data.threshold;
    }
    static isTrue(data) {
        logger.debug(`isTrue: ${JSON.stringify(data)}`);
        if (Array.isArray(data.value)) {
            if (data.evaluationType === EvaluateOverTimeType.AnyValue) {
                return data.value.some((value) => {
                    return value === true;
                });
            }
            return data.value.every((value) => {
                return value === true;
            });
        }
        return data.value === true;
    }
    static isFalse(data) {
        logger.debug(`isFalse: ${JSON.stringify(data)}`);
        if (Array.isArray(data.value)) {
            if (data.evaluationType === EvaluateOverTimeType.AnyValue) {
                return data.value.some((value) => {
                    return value === false;
                });
            }
            return data.value.every((value) => {
                return value === false;
            });
        }
        return data.value === false;
    }
    static lessThan(data) {
        if (Array.isArray(data.value)) {
            if (data.evaluationType === EvaluateOverTimeType.AnyValue) {
                return data.value.some((value) => {
                    return value < data.threshold;
                });
            }
            return data.value.every((value) => {
                return value < data.threshold;
            });
        }
        return data.value < data.threshold;
    }
    static greaterThanOrEqual(data) {
        if (Array.isArray(data.value)) {
            if (data.evaluationType === EvaluateOverTimeType.AnyValue) {
                return data.value.some((value) => {
                    return value >= data.threshold;
                });
            }
            return data.value.every((value) => {
                return value >= data.threshold;
            });
        }
        return data.value >= data.threshold;
    }
    static lessThanOrEqual(data) {
        if (Array.isArray(data.value)) {
            if (data.evaluationType === EvaluateOverTimeType.AnyValue) {
                return data.value.some((value) => {
                    return value <= data.threshold;
                });
            }
            return data.value.every((value) => {
                return value <= data.threshold;
            });
        }
        return data.value <= data.threshold;
    }
    static equalTo(data) {
        if (Array.isArray(data.value)) {
            if (data.evaluationType === EvaluateOverTimeType.AnyValue) {
                return data.value.some((value) => {
                    return value === data.threshold;
                });
            }
            return data.value.every((value) => {
                return value === data.threshold;
            });
        }
        return data.value === data.threshold;
    }
    static notEqualTo(data) {
        if (Array.isArray(data.value)) {
            if (data.evaluationType === EvaluateOverTimeType.AnyValue) {
                return data.value.some((value) => {
                    return value !== data.threshold;
                });
            }
            return data.value.every((value) => {
                return value !== data.threshold;
            });
        }
        return data.value !== data.threshold;
    }
    static convertToNumber(threshold) {
        if (threshold === undefined || threshold === null) {
            return null;
        }
        if (typeof threshold === Typeof.String) {
            try {
                threshold = parseInt(threshold);
            }
            catch (err) {
                logger.error(err);
                return null;
            }
        }
        if (typeof threshold !== Typeof.Number) {
            return null;
        }
        return threshold;
    }
    static checkEqualToOrNotEqualTo(data) {
        if (data.criteriaFilter.filterType === FilterType.EqualTo) {
            if (data.value === data.threshold) {
                return `${data.criteriaFilter.checkOn} is equal to ${data.threshold}.`;
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.NotEqualTo) {
            if (data.value !== data.threshold) {
                return `${data.criteriaFilter.checkOn} is not equal to ${data.threshold}.`;
            }
            return null;
        }
        return null;
    }
    static compareEmptyAndNotEmpty(data) {
        if (data.criteriaFilter.filterType === FilterType.IsEmpty) {
            if (data.value === null || data.value === undefined) {
                return `${data.criteriaFilter.checkOn} is empty.`;
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.IsNotEmpty) {
            if (data.value !== null && data.value !== undefined) {
                const valueStr = String(data.value);
                const truncatedValue = valueStr.length > 500 ? valueStr.substring(0, 500) + "..." : valueStr;
                return `${data.criteriaFilter.checkOn} is not empty. Value: ${truncatedValue}`;
            }
            return null;
        }
        return null;
    }
    static compareCriteriaStrings(data) {
        if (data.value === null || data.value === undefined) {
            return null;
        }
        if (data.threshold === null || data.threshold === undefined) {
            return null;
        }
        if (typeof data.value !== Typeof.String) {
            data.value = data.value.toString();
        }
        if (typeof data.threshold !== Typeof.String) {
            data.threshold = data.threshold.toString();
        }
        if (data.criteriaFilter.filterType === FilterType.Contains) {
            if (data.value.includes(data.threshold)) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                });
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.NotContains) {
            if (!data.value.includes(data.threshold)) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                });
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.StartsWith) {
            if (data.value.startsWith(data.threshold)) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                });
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.EndsWith) {
            if (data.value.endsWith(data.threshold)) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                });
            }
            return null;
        }
        // check equalto and not equal to
        const equalToOrNotEqualToResult = CompareCriteria.checkEqualToOrNotEqualTo({
            value: data.value,
            threshold: data.threshold,
            criteriaFilter: data.criteriaFilter,
        });
        if (equalToOrNotEqualToResult) {
            return equalToOrNotEqualToResult;
        }
        return null;
    }
    static compareCriteriaBoolean(data) {
        var _a, _b, _c, _d;
        logger.debug(`compareCriteriaBoolean: ${JSON.stringify(data)}`);
        if (data.value === null || data.value === undefined) {
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.True) {
            if (CompareCriteria.isTrue({
                value: data.value,
                evaluationType: ((_a = data.criteriaFilter.evaluateOverTimeOptions) === null || _a === void 0 ? void 0 : _a.evaluateOverTimeType) ||
                    ((_b = data.criteriaFilter.metricMonitorOptions) === null || _b === void 0 ? void 0 : _b.metricAggregationType),
            })) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: true,
                    criteriaFilter: data.criteriaFilter,
                });
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.False) {
            if (CompareCriteria.isFalse({
                value: data.value,
                evaluationType: ((_c = data.criteriaFilter.evaluateOverTimeOptions) === null || _c === void 0 ? void 0 : _c.evaluateOverTimeType) ||
                    ((_d = data.criteriaFilter.metricMonitorOptions) === null || _d === void 0 ? void 0 : _d.metricAggregationType),
            })) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: false,
                    criteriaFilter: data.criteriaFilter,
                });
            }
            return null;
        }
        return null;
    }
    static compareCriteriaNumbers(data) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
        if (data.value === null || data.value === undefined) {
            return null;
        }
        if (data.threshold === null || data.threshold === undefined) {
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.GreaterThan) {
            if (CompareCriteria.greaterThan({
                threshold: data.threshold,
                value: data.value,
                evaluationType: ((_a = data.criteriaFilter.evaluateOverTimeOptions) === null || _a === void 0 ? void 0 : _a.evaluateOverTimeType) ||
                    ((_b = data.criteriaFilter.metricMonitorOptions) === null || _b === void 0 ? void 0 : _b.metricAggregationType),
            })) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                    metricDisplayName: data.metricDisplayName,
                    unit: data.unit,
                });
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.LessThan) {
            if (CompareCriteria.lessThan({
                threshold: data.threshold,
                value: data.value,
                evaluationType: ((_c = data.criteriaFilter.evaluateOverTimeOptions) === null || _c === void 0 ? void 0 : _c.evaluateOverTimeType) ||
                    ((_d = data.criteriaFilter.metricMonitorOptions) === null || _d === void 0 ? void 0 : _d.metricAggregationType),
            })) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                    metricDisplayName: data.metricDisplayName,
                    unit: data.unit,
                });
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.EqualTo) {
            if (CompareCriteria.equalTo({
                threshold: data.threshold,
                value: data.value,
                evaluationType: ((_e = data.criteriaFilter.evaluateOverTimeOptions) === null || _e === void 0 ? void 0 : _e.evaluateOverTimeType) ||
                    ((_f = data.criteriaFilter.metricMonitorOptions) === null || _f === void 0 ? void 0 : _f.metricAggregationType),
            })) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                    metricDisplayName: data.metricDisplayName,
                    unit: data.unit,
                });
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.NotEqualTo) {
            if (CompareCriteria.notEqualTo({
                threshold: data.threshold,
                value: data.value,
                evaluationType: ((_g = data.criteriaFilter.evaluateOverTimeOptions) === null || _g === void 0 ? void 0 : _g.evaluateOverTimeType) ||
                    ((_h = data.criteriaFilter.metricMonitorOptions) === null || _h === void 0 ? void 0 : _h.metricAggregationType),
            })) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                    metricDisplayName: data.metricDisplayName,
                    unit: data.unit,
                });
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.GreaterThanOrEqualTo) {
            if (CompareCriteria.greaterThanOrEqual({
                threshold: data.threshold,
                value: data.value,
                evaluationType: ((_j = data.criteriaFilter.evaluateOverTimeOptions) === null || _j === void 0 ? void 0 : _j.evaluateOverTimeType) ||
                    ((_k = data.criteriaFilter.metricMonitorOptions) === null || _k === void 0 ? void 0 : _k.metricAggregationType),
            })) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                    metricDisplayName: data.metricDisplayName,
                    unit: data.unit,
                });
            }
            return null;
        }
        if (data.criteriaFilter.filterType === FilterType.LessThanOrEqualTo) {
            if (CompareCriteria.lessThanOrEqual({
                threshold: data.threshold,
                value: data.value,
                evaluationType: ((_l = data.criteriaFilter.evaluateOverTimeOptions) === null || _l === void 0 ? void 0 : _l.evaluateOverTimeType) ||
                    ((_m = data.criteriaFilter.metricMonitorOptions) === null || _m === void 0 ? void 0 : _m.metricAggregationType),
            })) {
                return CompareCriteria.getCompareMessage({
                    values: data.value,
                    threshold: data.threshold,
                    criteriaFilter: data.criteriaFilter,
                    metricDisplayName: data.metricDisplayName,
                    unit: data.unit,
                });
            }
            return null;
        }
        return null;
    }
    static getCompareMessage(data) {
        var _a, _b, _c, _d;
        // CPU Percent over the last 5 minutes is 10 which is less than the threshold of 20
        let message = "";
        let evaluationType = (_a = data.criteriaFilter.evaluateOverTimeOptions) === null || _a === void 0 ? void 0 : _a.evaluateOverTimeType;
        if ((_b = data.criteriaFilter.metricMonitorOptions) === null || _b === void 0 ? void 0 : _b.metricAggregationType) {
            evaluationType =
                data.criteriaFilter.metricMonitorOptions.metricAggregationType;
        }
        if (evaluationType === EvaluateOverTimeType.AnyValue) {
            message += "Any value of";
        }
        if (evaluationType === EvaluateOverTimeType.AllValues) {
            message += "All values of";
        }
        /*
         * Prefer a metric-specific display name over the generic "Metric Value"
         * label when evaluating metric monitors.
         */
        const label = data.metricDisplayName &&
            data.criteriaFilter.checkOn === CheckOn.MetricValue
            ? data.metricDisplayName
            : data.criteriaFilter.checkOn;
        message += ` ${label}`;
        if (data.criteriaFilter.checkOn === CheckOn.DiskUsagePercent) {
            const diskPath = ((_c = data.criteriaFilter.serverMonitorOptions) === null || _c === void 0 ? void 0 : _c.diskPath) || "/";
            message += ` on disk ${diskPath}`;
        }
        if (data.criteriaFilter.evaluateOverTime &&
            ((_d = data.criteriaFilter.evaluateOverTimeOptions) === null || _d === void 0 ? void 0 : _d.timeValueInMinutes)) {
            message += ` over the last ${data.criteriaFilter.evaluateOverTimeOptions.timeValueInMinutes} minutes`;
        }
        const unitSuffix = data.unit ? ` ${data.unit}` : "";
        if (data.criteriaFilter.filterType !== FilterType.True &&
            data.criteriaFilter.filterType !== FilterType.False) {
            const formattedValues = CompareCriteria.formatCriteriaValues(data.values);
            message += ` is ${formattedValues}${unitSuffix}`;
            message += " which is";
        }
        switch (data.criteriaFilter.filterType) {
            case FilterType.GreaterThan:
                message += ` greater than ${CompareCriteria.formatSingleValue(data.threshold)}${unitSuffix}. `;
                break;
            case FilterType.GreaterThanOrEqualTo:
                message += ` greater than or equal to ${CompareCriteria.formatSingleValue(data.threshold)}${unitSuffix}. `;
                break;
            case FilterType.LessThan:
                message += ` less than ${CompareCriteria.formatSingleValue(data.threshold)}${unitSuffix}. `;
                break;
            case FilterType.LessThanOrEqualTo:
                message += ` less than or equal to ${CompareCriteria.formatSingleValue(data.threshold)}${unitSuffix}. `;
                break;
            case FilterType.NotEqualTo:
                message += ` not equal to ${CompareCriteria.formatSingleValue(data.threshold)}${unitSuffix}. `;
                break;
            case FilterType.EqualTo:
                message += ` equal to ${CompareCriteria.formatSingleValue(data.threshold)}${unitSuffix}. `;
                break;
            case FilterType.Contains:
                message += ` contains ${CompareCriteria.formatSingleValue(data.threshold)}. `;
                break;
            case FilterType.NotContains:
                message += ` does not contain ${CompareCriteria.formatSingleValue(data.threshold)}. `;
                break;
            case FilterType.True:
                message += ` is ${data.threshold}. `;
                break;
            case FilterType.False:
                message += ` is ${data.threshold}. `;
                break;
            case FilterType.StartsWith:
                message += ` starts with ${CompareCriteria.formatSingleValue(data.threshold)}. `;
                break;
            case FilterType.EndsWith:
                message += ` ends with ${CompareCriteria.formatSingleValue(data.threshold)}. `;
                break;
        }
        return message.trim();
    }
    static formatCriteriaValues(values) {
        if (Array.isArray(values)) {
            /*
             * For a small number of values, list them verbatim so the message
             * reads naturally ("is 42, 55, 60"). For larger arrays, summarize
             * — dumping 30+ numbers on one line makes the root cause unreadable
             * and the detailed breakdown is shown in the Breaching Samples
             * table below.
             */
            const MAX_INLINE = 5;
            if (values.length <= MAX_INLINE) {
                return values
                    .map((value) => {
                    return CompareCriteria.formatSingleValue(value);
                })
                    .join(", ");
            }
            const numericValues = values.filter((value) => {
                return typeof value === "number" && Number.isFinite(value);
            });
            if (numericValues.length === values.length && numericValues.length > 0) {
                const min = Math.min(...numericValues);
                const max = Math.max(...numericValues);
                return `${numericValues.length} samples between ${CompareCriteria.formatSingleValue(min)} and ${CompareCriteria.formatSingleValue(max)}`;
            }
            // Fall back to a truncated list when not all values are numeric
            const head = values
                .slice(0, MAX_INLINE)
                .map((value) => {
                return CompareCriteria.formatSingleValue(value);
            })
                .join(", ");
            return `${head}, … (${values.length} values total)`;
        }
        return CompareCriteria.formatSingleValue(values);
    }
    static formatSingleValue(value) {
        if (value === null || value === undefined) {
            return "unknown";
        }
        if (typeof value === Typeof.Number) {
            const numericValue = value;
            if (Number.isInteger(numericValue)) {
                return numericValue.toString();
            }
            const roundedValue = Number(numericValue.toFixed(2));
            return roundedValue.toString();
        }
        if (typeof value === Typeof.Boolean) {
            return value ? "true" : "false";
        }
        return value.toString();
    }
}
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], CompareCriteria, "greaterThan", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], CompareCriteria, "isTrue", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], CompareCriteria, "isFalse", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], CompareCriteria, "lessThan", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], CompareCriteria, "greaterThanOrEqual", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], CompareCriteria, "lessThanOrEqual", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], CompareCriteria, "equalTo", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], CompareCriteria, "notEqualTo", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Object)
], CompareCriteria, "convertToNumber", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Object)
], CompareCriteria, "checkEqualToOrNotEqualTo", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Object)
], CompareCriteria, "compareEmptyAndNotEmpty", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Object)
], CompareCriteria, "compareCriteriaStrings", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Object)
], CompareCriteria, "compareCriteriaBoolean", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Object)
], CompareCriteria, "compareCriteriaNumbers", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", String)
], CompareCriteria, "getCompareMessage", null);
//# sourceMappingURL=CompareCriteria.js.map