/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.cassandra.config;

import java.time.Duration;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.google.common.primitives.Ints;

import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized;

/**
 * Represents a positive time duration. Wrapper class for Cassandra duration configuration parameters, providing to the
 * users the opportunity to be able to provide config with a unit of their choice in cassandra.yaml as per the available
 * options. (CASSANDRA-15234)
 */
public abstract class DurationSpec
{
    /**
     * The Regexp used to parse the duration provided as String.
     */
    private static final Pattern UNITS_PATTERN = Pattern.compile(("^(\\d+)(d|h|s|ms|us|µs|ns|m)$"));

    private final long quantity;

    private final TimeUnit unit;

    private DurationSpec(long quantity, TimeUnit unit, TimeUnit minUnit, long max)
    {
        this.quantity = quantity;
        this.unit = unit;

        validateMinUnit(unit, minUnit, quantity + " " + unit);
        validateQuantity(quantity, unit, minUnit, max);
    }

    private DurationSpec(double quantity, TimeUnit unit, TimeUnit minUnit, long max)
    {
        this(Math.round(quantity), unit, minUnit, max);
    }

    private DurationSpec(String value, TimeUnit minUnit)
    {
        Matcher matcher = UNITS_PATTERN.matcher(value);

        if (matcher.find())
        {
            quantity = Long.parseLong(matcher.group(1));
            unit = fromSymbol(matcher.group(2));

            // this constructor is used only by extended classes for min unit; upper bound and min unit are guarded there accordingly
        }
        else
        {
            throw new IllegalArgumentException("Invalid duration: " + value + " Accepted units:" + acceptedUnits(minUnit) +
                                               " where case matters and only non-negative values.");
        }
    }

    private DurationSpec(String value, TimeUnit minUnit, long max)
    {
        this(value, minUnit);

        validateMinUnit(unit, minUnit, value);
        validateQuantity(value, quantity(), unit(), minUnit, max);
    }

    private static void validateMinUnit(TimeUnit unit, TimeUnit minUnit, String value)
    {
        if (unit.compareTo(minUnit) < 0)
            throw new IllegalArgumentException(String.format("Invalid duration: %s Accepted units:%s", value, acceptedUnits(minUnit)));
    }

    private static String acceptedUnits(TimeUnit minUnit)
    {
        TimeUnit[] units = TimeUnit.values();
        return Arrays.toString(Arrays.copyOfRange(units, minUnit.ordinal(), units.length));
    }

    private static void validateQuantity(String value, long quantity, TimeUnit sourceUnit, TimeUnit minUnit, long max)
    {
        // no need to validate for negatives as they are not allowed at first place from the regex

        if (minUnit.convert(quantity, sourceUnit) >= max)
            throw new IllegalArgumentException("Invalid duration: " + value + ". It shouldn't be more than " +
                                             (max - 1) + " in " + toLowerCaseLocalized(minUnit.name()));
    }

    private static void validateQuantity(long quantity, TimeUnit sourceUnit, TimeUnit minUnit, long max)
    {
        if (quantity < 0)
            throw new IllegalArgumentException("Invalid duration: value must be non-negative");

        if (minUnit.convert(quantity, sourceUnit) >= max)
            throw new IllegalArgumentException(String.format("Invalid duration: %d %s. It shouldn't be more than %d in %s",
                                                           quantity, toLowerCaseLocalized(sourceUnit.name()),
                                                           max - 1, toLowerCaseLocalized(minUnit.name())));
    }

    // get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is
    // imporant to be explicit about get/set as this changes how parsing is done; this class is a data-type, so is
    // not nested, having get/set can confuse parsing thinking this is a nested type
    public long quantity()
    {
        return quantity;
    }

    public TimeUnit unit()
    {
        return unit;
    }

    public Duration toDuration()
    {
        return Duration.of(quantity(), unit().toChronoUnit());
    }

    /**
     * @param symbol the time unit symbol
     * @return the time unit associated to the specified symbol
     */
    public static TimeUnit fromSymbol(String symbol)
    {
        switch (toLowerCaseLocalized(symbol))
        {
            case "d": return DAYS;
            case "h": return HOURS;
            case "m": return MINUTES;
            case "s": return SECONDS;
            case "ms": return MILLISECONDS;
            case "us":
            case "µs": return MICROSECONDS;
            case "ns": return TimeUnit.NANOSECONDS;
        }
        throw new IllegalArgumentException(String.format("Unsupported time unit: %s. Supported units are: %s",
                                                       symbol, Arrays.stream(TimeUnit.values())
                                                                     .map(DurationSpec::symbol)
                                                                     .collect(Collectors.joining(", "))));
    }

    /**
     * @param targetUnit the time unit
     * @return this duration in the specified time unit
     */
    public long to(TimeUnit targetUnit)
    {
        return targetUnit.convert(quantity, unit);
    }

    @Override
    public int hashCode()
    {
        // Milliseconds seems to be a reasonable tradeoff
        return Objects.hash(unit.toMillis(quantity));
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;

        if (!(obj instanceof DurationSpec))
            return false;

        DurationSpec other = (DurationSpec) obj;
        if (unit == other.unit)
            return quantity == other.quantity;

        // Due to overflows we can only guarantee that the 2 durations are equal if we get the same results
        // doing the conversion in both directions.
        return unit.convert(other.quantity, other.unit) == quantity && other.unit.convert(quantity, unit) == other.quantity;
    }

    @Override
    public String toString()
    {
        return quantity + symbol(unit);
    }

    /**
     * Returns the symbol associated to the specified unit
     *
     * @param unit the time unit
     * @return the time unit symbol
     */
    // get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is
    // imporant to be explicit about get/set as this changes how parsing is done; this class is a data-type, so is
    // not nested, having get/set can confuse parsing thinking this is a nested type
    static String symbol(TimeUnit unit)
    {
        switch (unit)
        {
            case DAYS: return "d";
            case HOURS: return "h";
            case MINUTES: return "m";
            case SECONDS: return "s";
            case MILLISECONDS: return "ms";
            case MICROSECONDS: return "us";
            case NANOSECONDS: return "ns";
        }
        throw new AssertionError();
    }

    /**
     * Represents a duration used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in nanoseconds.
     * If the user sets a different unit - we still validate that converted to nanoseconds the quantity will not exceed
     * that upper bound. (CASSANDRA-17571)
     */
    public final static class LongNanosecondsBound extends DurationSpec
    {
        /**
         * Creates a {@code DurationSpec.LongNanosecondsBound} of the specified amount.
         * The bound is [0, Long.MAX_VALUE) in nanoseconds.
         *
         * @param value the duration
         */
        public LongNanosecondsBound(String value)
        {
            super(value, NANOSECONDS, Long.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.LongNanosecondsBound} of the specified amount in the specified unit.
         * The bound is [0, Long.MAX_VALUE) in nanoseconds.
         *
         * @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in nanoseconds
         * @param unit in which the provided quantity is
         */
        public LongNanosecondsBound(long quantity, TimeUnit unit)
        {
            super(quantity, unit, NANOSECONDS, Long.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.LongNanosecondsBound} of the specified amount in nanoseconds.
         * The bound is [0, Long.MAX_VALUE) in nanoseconds.
         *
         * @param nanoseconds where nanoseconds shouldn't be bigger than Long.MAX_VALUE-1
         */
        public LongNanosecondsBound(long nanoseconds)
        {
            this(nanoseconds, NANOSECONDS);
        }

        /**
         * @return this duration in number of nanoseconds
         */
        public long toNanoseconds()
        {
            return unit().toNanos(quantity());
        }
    }

    /**
     * Represents a duration used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in microseconds.
     * If the user sets a different unit - we still validate that converted to microseconds the quantity will not exceed
     * that upper bound. (CASSANDRA-17571)
     */
    public final static class LongMicrosecondsBound extends DurationSpec
    {
        /**
         * Creates a {@code DurationSpec.LongMicrosecondsBound} of the specified amount.
         * The bound is [0, Long.MAX_VALUE) in microseconds.
         *
         * @param value the duration
         */
        public LongMicrosecondsBound(String value)
        {
            super(value, MICROSECONDS, Long.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.LongMicrosecondsBound} of the specified amount in the specified unit.
         * The bound is [0, Long.MAX_VALUE) in milliseconds.
         *
         * @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in microseconds
         * @param unit in which the provided quantity is
         */
        public LongMicrosecondsBound(long quantity, TimeUnit unit)
        {
            super(quantity, unit, MICROSECONDS, Long.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.LongMicrosecondsBound} of the specified amount in microseconds.
         * The bound is [0, Long.MAX_VALUE) in microseconds.
         *
         * @param microseconds where milliseconds shouldn't be bigger than Long.MAX_VALUE-1
         */
        public LongMicrosecondsBound(long microseconds)
        {
            this(microseconds, MICROSECONDS);
        }

        /**
         * @return this duration in number of milliseconds
         */
        public long toMicroseconds()
        {
            return unit().toMicros(quantity());
        }

        /**
         * @return this duration in number of seconds
         */
        public long toSeconds()
        {
            return unit().toSeconds(quantity());
        }
    }

    /**
     * Represents a duration used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in milliseconds.
     * If the user sets a different unit - we still validate that converted to milliseconds the quantity will not exceed
     * that upper bound. (CASSANDRA-17571)
     */
    public final static class LongMillisecondsBound extends DurationSpec
    {
        /**
         * Creates a {@code DurationSpec.LongMillisecondsBound} of the specified amount.
         * The bound is [0, Long.MAX_VALUE) in milliseconds.
         *
         * @param value the duration
         */
        public LongMillisecondsBound(String value)
        {
            super(value, MILLISECONDS, Long.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.LongMillisecondsBound} of the specified amount in the specified unit.
         * The bound is [0, Long.MAX_VALUE) in milliseconds.
         *
         * @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in milliseconds
         * @param unit in which the provided quantity is
         */
        public LongMillisecondsBound(long quantity, TimeUnit unit)
        {
            super(quantity, unit, MILLISECONDS, Long.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.LongMillisecondsBound} of the specified amount in milliseconds.
         * The bound is [0, Long.MAX_VALUE) in milliseconds.
         *
         * @param milliseconds where milliseconds shouldn't be bigger than Long.MAX_VALUE-1
         */
        public LongMillisecondsBound(long milliseconds)
        {
            this(milliseconds, MILLISECONDS);
        }

        /**
         * @return this duration in number of milliseconds
         */
        public long toMilliseconds()
        {
            return unit().toMillis(quantity());
        }
    }

    /**
     * Represents a duration used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in seconds.
     * If the user sets a different unit - we still validate that converted to seconds the quantity will not exceed
     * that upper bound. (CASSANDRA-17571)
     */
    public final static class LongSecondsBound extends DurationSpec
    {
        /**
         * Creates a {@code DurationSpec.LongSecondsBound} of the specified amount.
         * The bound is [0, Long.MAX_VALUE) in seconds.
         *
         * @param value the duration
         */
        public LongSecondsBound(String value)
        {
            super(value, SECONDS, Long.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.LongSecondsBound} of the specified amount in the specified unit.
         * The bound is [0, Long.MAX_VALUE) in seconds.
         *
         * @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in seconds
         * @param unit in which the provided quantity is
         */
        public LongSecondsBound(long quantity, TimeUnit unit)
        {
            super(quantity, unit, SECONDS, Long.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.LongSecondsBound} of the specified amount in seconds.
         * The bound is [0, Long.MAX_VALUE) in seconds.
         *
         * @param seconds where seconds shouldn't be bigger than Long.MAX_VALUE-1
         */
        public LongSecondsBound(long seconds)
        {
            this(seconds, SECONDS);
        }

        /**
         * @return this duration in number of milliseconds
         */
        public long toMilliseconds()
        {
            return unit().toMillis(quantity());
        }

        /**
         * @return this duration in number of seconds
         */
        public long toSeconds()
        {
            return unit().toSeconds(quantity());
        }
    }

    /**
     * Represents a duration used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in minutes.
     * If the user sets a different unit - we still validate that converted to minutes the quantity will not exceed
     * that upper bound. (CASSANDRA-17571)
     */
    public final static class IntMinutesBound extends DurationSpec
    {
        /**
         * Creates a {@code DurationSpec.IntMinutesBound} of the specified amount. The bound is [0, Integer.MAX_VALUE) in minutes.
         * The bound is [0, Integer.MAX_VALUE) in minutes.
         *
         * @param value the duration
         */
        public IntMinutesBound(String value)
        {
            super(value, MINUTES, Integer.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.IntMinutesBound} of the specified amount in the specified unit.
         * The bound is [0, Integer.MAX_VALUE) in minutes.
         *
         * @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in minutes
         * @param unit in which the provided quantity is
         */
        public IntMinutesBound(long quantity, TimeUnit unit)
        {
            super(quantity, unit, MINUTES, Integer.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.IntMinutesBound} of the specified amount in minutes.
         * The bound is [0, Integer.MAX_VALUE) in minutes.
         *
         * @param minutes where minutes shouldn't be bigger than Integer.MAX_VALUE-1
         */
        public IntMinutesBound(long minutes)
        {
            this(minutes, MINUTES);
        }

        /**
         * Returns this duration in number of milliseconds as an {@code int}
         *
         * @return this duration in number of milliseconds or {@code Integer.MAX_VALUE} if the number of milliseconds is too large.
         */
        public int toMilliseconds()
        {
            return Ints.saturatedCast(unit().toMillis(quantity()));
        }

        /**
         * Returns this duration in number of seconds as an {@code int}
         *
         * @return this duration in number of seconds or {@code Integer.MAX_VALUE} if the number of seconds is too large.
         */
        public int toSeconds()
        {
            return Ints.saturatedCast(unit().toSeconds(quantity()));
        }

        /**
         * Returns this duration in number of minutes as an {@code int}
         *
         * @return this duration in number of minutes or {@code Integer.MAX_VALUE} if the number of minutes is too large.
         */
        public int toMinutes()
        {
            return Ints.saturatedCast(unit().toMinutes(quantity()));
        }
    }

    /**
     * Represents a duration used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in seconds.
     * If the user sets a different unit - we still validate that converted to seconds the quantity will not exceed
     * that upper bound. (CASSANDRA-17571)
     */
    public final static class IntSecondsBound extends DurationSpec
    {
        private static final Pattern VALUES_PATTERN = Pattern.compile(("\\d+"));

        /**
         * Creates a {@code DurationSpec.IntSecondsBound} of the specified amount. The bound is [0, Integer.MAX_VALUE) in seconds.
         * The bound is [0, Integer.MAX_VALUE) in seconds.
         *
         * @param value the duration
         */
        public IntSecondsBound(String value)
        {
            super(value, SECONDS, Integer.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.IntSecondsBound} of the specified amount in the specified unit.
         * The bound is [0, Integer.MAX_VALUE) in seconds.
         *
         * @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in seconds
         * @param unit in which the provided quantity is
         */
        public IntSecondsBound(long quantity, TimeUnit unit)
        {
            super(quantity, unit, SECONDS, Integer.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.IntSecondsBound} of the specified amount in seconds.
         * The bound is [0, Integer.MAX_VALUE) in seconds.
         *
         * @param seconds where seconds shouldn't be bigger than Integer.MAX_VALUE-1
         */
        public IntSecondsBound(long seconds)
        {
            this(seconds, SECONDS);
        }

        /**
         * Creates a {@code DurationSpec.IntSecondsBound} of the specified amount in seconds, expressed either as the
         * number of seconds without unit, or as a regular quantity with unit.
         * Used in the Converters for a few parameters which changed only type, but not names
         * The bound is [0, Integer.MAX_VALUE) in seconds.
         *
         * @param value where value shouldn't be bigger than Integer.MAX_VALUE-1 in seconds
         */
        public static IntSecondsBound inSecondsString(String value)
        {
            //parse the string field value
            Matcher matcher = VALUES_PATTERN.matcher(value);

            long seconds;
            //if the provided string value is just a number, then we create a IntSecondsBound value in seconds
            if (matcher.matches())
            {
                seconds = Integer.parseInt(value);
                return new IntSecondsBound(seconds, TimeUnit.SECONDS);
            }

            //otherwise we just use the standard constructors
            return new IntSecondsBound(value);
        }

        /**
         * Returns this duration in the number of nanoseconds as a {@code long}
         */
        public long toNanoseconds()
        {
            return unit().toNanos(quantity());
        }

        /**
         * Returns this duration in number of milliseconds as an {@code int}
         *
         * @return this duration in number of milliseconds or {@code Integer.MAX_VALUE} if the number of milliseconds is too large.
         */
        public int toMilliseconds()
        {
            return Ints.saturatedCast(unit().toMillis(quantity()));
        }

        /**
         * Returns this duration in number of seconds as an {@code int}
         *
         * @return this duration in number of seconds or {@code Integer.MAX_VALUE} if the number of seconds is too large.
         */
        public int toSeconds()
        {
            return Ints.saturatedCast(unit().toSeconds(quantity()));
        }
    }

    /**
     * Represents a duration used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in milliseconds.
     * If the user sets a different unit - we still validate that converted to milliseconds the quantity will not exceed
     * that upper bound. (CASSANDRA-17571)
     */
    public final static class IntMillisecondsBound extends DurationSpec
    {
        /**
         * Creates a {@code DurationSpec.IntMillisecondsBound} of the specified amount. The bound is [0, Integer.MAX_VALUE) in milliseconds.
         * The bound is [0, Integer.MAX_VALUE) in milliseconds.
         *
         * @param value the duration
         */
        public IntMillisecondsBound(String value)
        {
            super(value, MILLISECONDS, Integer.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.IntMillisecondsBound} of the specified amount in the specified unit.
         * The bound is [0, Integer.MAX_VALUE) in milliseconds.
         *
         * @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in milliseconds
         * @param unit in which the provided quantity is
         */
        public IntMillisecondsBound(long quantity, TimeUnit unit)
        {
            super(quantity, unit, MILLISECONDS, Integer.MAX_VALUE);
        }

        /**
         * Creates a {@code DurationSpec.IntMillisecondsBound} of the specified amount in milliseconds.
         * The bound is [0, Integer.MAX_VALUE) in milliseconds.
         *
         * @param milliseconds where milliseconds shouldn't be bigger than Integer.MAX_VALUE-1
         */
        public IntMillisecondsBound(long milliseconds)
        {
            this(milliseconds, MILLISECONDS);
        }

        /**
         * Below constructor is used only for backward compatibility for the old commitlog_sync_group_window_in_ms before 4.1
         * Creates a {@code DurationSpec.IntMillisecondsBound} of the specified amount in the specified unit.
         *
         * @param quantity where quantity shouldn't be bigger than Intetger.MAX_VALUE - 1 in milliseconds
         * @param unit in which the provided quantity is
         */
        public IntMillisecondsBound(double quantity, TimeUnit unit)
        {
            super(quantity, unit, MILLISECONDS, Integer.MAX_VALUE);
        }

        /**
         * Returns this duration in number of milliseconds as an {@code int}
         *
         * @return this duration in number of milliseconds or {@code Integer.MAX_VALUE} if the number of milliseconds is too large.
         */
        public int toMilliseconds()
        {
            return Ints.saturatedCast(unit().toMillis(quantity()));
        }
    }
}
