import OneUptimeDate from "../../../../Types/Date";
import NotImplementedException from "../../../../Types/Exception/NotImplementedException";
import XAxisPrecision from "../Types/XAxis/XAxisPrecision";
export default class XAxisUtil {
    static cloneDate(value) {
        return new Date(value.getTime());
    }
    static getPrecision(data) {
        if (typeof data.xAxisMax === "number" ||
            typeof data.xAxisMin === "number") {
            // number not yet supported.
            throw new NotImplementedException();
        }
        const startDate = OneUptimeDate.fromString(data.xAxisMin);
        const endDate = OneUptimeDate.fromString(data.xAxisMax);
        const totalMilliseconds = endDate.getTime() - startDate.getTime();
        const totalSeconds = totalMilliseconds / 1000;
        const totalMinutes = totalSeconds / 60;
        const totalHours = totalMinutes / 60;
        const totalDays = totalHours / 24;
        const totalWeeks = totalDays / 7;
        const totalMonths = totalDays / 30;
        /*
         * Mirror the server's aggregation interval (see
         * AggregateUtil.getAggregationInterval) so the chart renders one
         * point per backend bucket instead of re-bucketing them into
         * coarser groups. Previously a 1h range was rendered with EVERY_
         * FIVE_MINUTES (~12 points) even though the server returned 60
         * per-minute rows. Recharts thins the X-axis label set via
         * `interval="equidistantPreserveStart"`, so high point counts do
         * not crowd the labels.
         */
        if (totalSeconds <= 15) {
            return XAxisPrecision.EVERY_SECOND;
        }
        if (totalSeconds <= 75) {
            return XAxisPrecision.EVERY_FIVE_SECONDS;
        }
        if (totalSeconds <= 150) {
            return XAxisPrecision.EVERY_TEN_SECONDS;
        }
        if (totalSeconds <= 450) {
            return XAxisPrecision.EVERY_THIRTY_SECONDS;
        }
        if (totalHours <= 3) {
            return XAxisPrecision.EVERY_MINUTE;
        }
        if (totalDays <= 7) {
            return XAxisPrecision.EVERY_HOUR;
        }
        if (totalWeeks <= 6) {
            return XAxisPrecision.EVERY_DAY;
        }
        if (totalMonths <= 6) {
            return XAxisPrecision.EVERY_WEEK;
        }
        if (totalMonths <= 72) {
            return XAxisPrecision.EVERY_MONTH;
        }
        return XAxisPrecision.EVERY_YEAR;
    }
    static getPrecisionIntervals(data) {
        const precision = XAxisUtil.getPrecision(data);
        if (typeof data.xAxisMax === "number" ||
            typeof data.xAxisMin === "number") {
            // number not yet supported.
            throw new NotImplementedException();
        }
        const startDate = new Date(data.xAxisMin);
        const endDate = new Date(data.xAxisMax);
        const intervals = [];
        const currentDate = new Date(startDate);
        while (currentDate <= endDate) {
            intervals.push(new Date(currentDate));
            switch (precision) {
                case XAxisPrecision.EVERY_SECOND:
                    currentDate.setSeconds(currentDate.getSeconds() + 1);
                    break;
                case XAxisPrecision.EVERY_FIVE_SECONDS:
                    currentDate.setSeconds(currentDate.getSeconds() + 5);
                    break;
                case XAxisPrecision.EVERY_TEN_SECONDS:
                    currentDate.setSeconds(currentDate.getSeconds() + 10);
                    break;
                case XAxisPrecision.EVERY_THIRTY_SECONDS:
                    currentDate.setSeconds(currentDate.getSeconds() + 30);
                    break;
                case XAxisPrecision.EVERY_MINUTE:
                    currentDate.setMinutes(currentDate.getMinutes() + 1);
                    break;
                case XAxisPrecision.EVERY_FIVE_MINUTES:
                    currentDate.setMinutes(currentDate.getMinutes() + 5);
                    break;
                case XAxisPrecision.EVERY_TEN_MINUTES:
                    currentDate.setMinutes(currentDate.getMinutes() + 10);
                    break;
                case XAxisPrecision.EVERY_THIRTY_MINUTES:
                    currentDate.setMinutes(currentDate.getMinutes() + 30);
                    break;
                case XAxisPrecision.EVERY_HOUR:
                    currentDate.setHours(currentDate.getHours() + 1);
                    break;
                case XAxisPrecision.EVERY_TWO_HOURS:
                    currentDate.setHours(currentDate.getHours() + 2);
                    break;
                case XAxisPrecision.EVERY_THREE_HOURS:
                    currentDate.setHours(currentDate.getHours() + 3);
                    break;
                case XAxisPrecision.EVERY_SIX_HOURS:
                    currentDate.setHours(currentDate.getHours() + 6);
                    break;
                case XAxisPrecision.EVERY_TWELVE_HOURS:
                    currentDate.setHours(currentDate.getHours() + 12);
                    break;
                case XAxisPrecision.EVERY_DAY:
                    currentDate.setDate(currentDate.getDate() + 1);
                    break;
                case XAxisPrecision.EVERY_TWO_DAYS:
                    currentDate.setDate(currentDate.getDate() + 2);
                    break;
                case XAxisPrecision.EVERY_WEEK:
                    currentDate.setDate(currentDate.getDate() + 7);
                    break;
                case XAxisPrecision.EVERY_TWO_WEEKS:
                    currentDate.setDate(currentDate.getDate() + 14);
                    break;
                case XAxisPrecision.EVERY_MONTH:
                    currentDate.setMonth(currentDate.getMonth() + 1);
                    break;
                case XAxisPrecision.EVERY_TWO_MONTHS:
                    currentDate.setMonth(currentDate.getMonth() + 2);
                    break;
                case XAxisPrecision.EVERY_THREE_MONTHS:
                    currentDate.setMonth(currentDate.getMonth() + 3);
                    break;
                case XAxisPrecision.EVERY_SIX_MONTHS:
                    currentDate.setMonth(currentDate.getMonth() + 6);
                    break;
                case XAxisPrecision.EVERY_YEAR:
                    currentDate.setFullYear(currentDate.getFullYear() + 1);
                    break;
            }
        }
        return intervals;
    }
    static getFormatter(data) {
        const precision = XAxisUtil.getPrecision(data);
        switch (precision) {
            case XAxisPrecision.EVERY_SECOND:
                return (value) => {
                    return OneUptimeDate.getLocalTimeString(value, {
                        includeSeconds: true,
                    });
                };
            case XAxisPrecision.EVERY_FIVE_SECONDS:
                // round down to nearest 5 seconds
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const seconds = roundedValue.getSeconds();
                    const roundedSeconds = Math.floor(seconds / 5) * 5;
                    roundedValue.setSeconds(roundedSeconds, 0);
                    return OneUptimeDate.getLocalTimeString(roundedValue, {
                        includeSeconds: true,
                    });
                };
            case XAxisPrecision.EVERY_TEN_SECONDS:
                // round down to nearest 10 seconds
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const seconds = roundedValue.getSeconds();
                    const roundedSeconds = Math.floor(seconds / 10) * 10;
                    roundedValue.setSeconds(roundedSeconds, 0);
                    return OneUptimeDate.getLocalTimeString(roundedValue, {
                        includeSeconds: true,
                    });
                };
            case XAxisPrecision.EVERY_THIRTY_SECONDS:
                // round down to nearest 30 seconds
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const seconds = roundedValue.getSeconds();
                    const roundedSeconds = Math.floor(seconds / 30) * 30;
                    roundedValue.setSeconds(roundedSeconds, 0);
                    return OneUptimeDate.getLocalTimeString(roundedValue, {
                        includeSeconds: true,
                    });
                };
            case XAxisPrecision.EVERY_MINUTE:
                // round down to nearest minute
                return (value) => {
                    return OneUptimeDate.getLocalTimeString(value);
                };
            case XAxisPrecision.EVERY_FIVE_MINUTES:
                // round down to nearest 5 minutes
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const minutes = roundedValue.getMinutes();
                    const roundedMinutes = Math.floor(minutes / 5) * 5;
                    roundedValue.setMinutes(roundedMinutes, 0, 0);
                    return OneUptimeDate.getLocalTimeString(roundedValue);
                };
            case XAxisPrecision.EVERY_TEN_MINUTES:
                // round down to nearest 10 minutes
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const minutes = roundedValue.getMinutes();
                    const roundedMinutes = Math.floor(minutes / 10) * 10;
                    roundedValue.setMinutes(roundedMinutes, 0, 0);
                    return OneUptimeDate.getLocalTimeString(roundedValue);
                };
            case XAxisPrecision.EVERY_THIRTY_MINUTES:
                // round down to nearest 30 minutes
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const minutes = roundedValue.getMinutes();
                    const roundedMinutes = Math.floor(minutes / 30) * 30;
                    roundedValue.setMinutes(roundedMinutes, 0, 0);
                    return OneUptimeDate.getLocalTimeString(roundedValue);
                };
            case XAxisPrecision.EVERY_HOUR:
                /*
                 * Include date — hourly buckets can span multiple days, where
                 * a bare "HH" repeats and is ambiguous.
                 */
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    roundedValue.setMinutes(0, 0, 0);
                    return OneUptimeDate.getDateAsLocalDayMonthHourString(roundedValue);
                };
            case XAxisPrecision.EVERY_TWO_HOURS:
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const hours = roundedValue.getHours();
                    const roundedHours = Math.floor(hours / 2) * 2;
                    roundedValue.setHours(roundedHours, 0, 0, 0);
                    return OneUptimeDate.getDateAsLocalDayMonthHourString(roundedValue);
                };
            case XAxisPrecision.EVERY_THREE_HOURS:
                // round down to nearest 3 hours
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const hours = roundedValue.getHours();
                    const roundedHours = Math.floor(hours / 3) * 3;
                    roundedValue.setHours(roundedHours, 0, 0, 0);
                    return OneUptimeDate.getDateAsLocalDayMonthHourString(roundedValue);
                };
            case XAxisPrecision.EVERY_SIX_HOURS:
                // round down to nearest 6 hours // HH:00 DD MMM
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const hours = roundedValue.getHours();
                    const roundedHours = Math.floor(hours / 6) * 6;
                    roundedValue.setHours(roundedHours, 0, 0, 0);
                    return OneUptimeDate.getDateAsLocalDayMonthHourString(roundedValue);
                };
            case XAxisPrecision.EVERY_TWELVE_HOURS:
                // round down to nearest 12 hours  // DD MMM, HH:00
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const hours = roundedValue.getHours();
                    const roundedHours = Math.floor(hours / 12) * 12;
                    roundedValue.setHours(roundedHours, 0, 0, 0);
                    return OneUptimeDate.getDateAsLocalDayMonthHourString(roundedValue);
                };
            case XAxisPrecision.EVERY_DAY:
                // round down to nearest day
                return (value) => {
                    return OneUptimeDate.getDateAsLocalDayMonthString(value);
                };
            case XAxisPrecision.EVERY_TWO_DAYS:
                // round down to nearest 2 days
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const days = roundedValue.getDate();
                    const roundedDays = Math.floor(days / 2) * 2;
                    roundedValue.setDate(roundedDays);
                    return OneUptimeDate.getDateAsLocalDayMonthString(roundedValue);
                };
            case XAxisPrecision.EVERY_WEEK:
                // round down to nearest week
                return (value) => {
                    const day = value.getDate().toString();
                    const month = OneUptimeDate.getLocalShortMonthNameFromDate(value);
                    return `${day} ${month}`;
                };
            case XAxisPrecision.EVERY_TWO_WEEKS:
                // round down to nearest 2 weeks. // DD MMM
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const days = roundedValue.getDate();
                    const roundedDays = Math.floor(days / 2) * 2;
                    roundedValue.setDate(roundedDays);
                    const day = roundedValue.getDate().toString();
                    const month = OneUptimeDate.getLocalShortMonthNameFromDate(roundedValue);
                    return `${day} ${month}`;
                };
            case XAxisPrecision.EVERY_MONTH:
                // round down to nearest month // MM YYYY
                return (value) => {
                    return OneUptimeDate.getDateAsLocalMonthYearString(value);
                };
            case XAxisPrecision.EVERY_TWO_MONTHS:
                // round down to nearest 2 months // MM YYYY
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const months = roundedValue.getMonth();
                    const roundedMonths = Math.floor(months / 2) * 2;
                    roundedValue.setMonth(roundedMonths);
                    return OneUptimeDate.getDateAsLocalMonthYearString(roundedValue);
                };
            case XAxisPrecision.EVERY_THREE_MONTHS:
                // round down to nearest 3 months // MM YYYY
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const months = roundedValue.getMonth();
                    const roundedMonths = Math.floor(months / 3) * 3;
                    roundedValue.setMonth(roundedMonths);
                    return OneUptimeDate.getDateAsLocalMonthYearString(roundedValue);
                };
            case XAxisPrecision.EVERY_SIX_MONTHS:
                // round down to nearest 6 months // MM YYYY
                return (value) => {
                    const roundedValue = this.cloneDate(value);
                    const months = roundedValue.getMonth();
                    const roundedMonths = Math.floor(months / 6) * 6;
                    roundedValue.setMonth(roundedMonths);
                    return OneUptimeDate.getDateAsLocalMonthYearString(roundedValue);
                };
            case XAxisPrecision.EVERY_YEAR:
                // round down to nearest year // YYYY
                return (value) => {
                    return value.getFullYear().toString();
                };
            default:
                throw new Error("Unsupported precision");
        }
    }
}
//# sourceMappingURL=XAxis.js.map