/*
 * 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.logging.log4j.core.appender.rolling.action;

import java.io.Serializable;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Simplified implementation of the <a href="https://en.wikipedia.org/wiki/ISO_8601#Durations">ISO-8601 Durations</a>
 * standard. The supported format is {@code PnDTnHnMnS}, with 'P' and 'T' optional. Days are considered to be exactly 24
 * hours.
 * <p>
 * Similarly to the {@code java.time.Duration} class, this class does not support year or month sections in the format.
 * This implementation does not support fractions or negative values.
 * 
 * @see #parse(CharSequence)
 */
public class Duration implements Serializable, Comparable<Duration> {
    private static final long serialVersionUID = -3756810052716342061L;

    /**
     * Constant for a duration of zero.
     */
    public static final Duration ZERO = new Duration(0);

    /**
     * Hours per day.
     */
    private static final int HOURS_PER_DAY = 24;
    /**
     * Minutes per hour.
     */
    private static final int MINUTES_PER_HOUR = 60;
    /**
     * Seconds per minute.
     */
    private static final int SECONDS_PER_MINUTE = 60;
    /**
     * Seconds per hour.
     */
    private static final int SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
    /**
     * Seconds per day.
     */
    private static final int SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;

    /**
     * The pattern for parsing.
     */
    private static final Pattern PATTERN = Pattern.compile("P?(?:([0-9]+)D)?"
            + "(T?(?:([0-9]+)H)?(?:([0-9]+)M)?(?:([0-9]+)?S)?)?", Pattern.CASE_INSENSITIVE);

    /**
     * The number of seconds in the duration.
     */
    private final long seconds;

    /**
     * Constructs an instance of {@code Duration} using seconds.
     *
     * @param seconds the length of the duration in seconds, positive or negative
     */
    private Duration(final long seconds) {
        super();
        this.seconds = seconds;
    }

    /**
     * Obtains a {@code Duration} from a text string such as {@code PnDTnHnMnS}.
     * <p>
     * This will parse a textual representation of a duration, including the string produced by {@code toString()}. The
     * formats accepted are based on the ISO-8601 duration format {@code PnDTnHnMnS} with days considered to be exactly
     * 24 hours.
     * <p>
     * This implementation does not support negative numbers or fractions (so the smallest non-zero value a Duration can
     * have is one second).
     * <p>
     * The string optionally starts with the ASCII letter "P" in upper or lower case. There are then four sections, each
     * consisting of a number and a suffix. The sections have suffixes in ASCII of "D", "H", "M" and "S" for days,
     * hours, minutes and seconds, accepted in upper or lower case. The suffixes must occur in order. The ASCII letter
     * "T" may occur before the first occurrence, if any, of an hour, minute or second section. At least one of the four
     * sections must be present, and if "T" is present there must be at least one section after the "T". The number part
     * of each section must consist of one or more ASCII digits. The number may not be prefixed by the ASCII negative or
     * positive symbol. The number of days, hours, minutes and seconds must parse to a {@code long}.
     * <p>
     * Examples:
     * 
     * <pre>
     *    "PT20S" -- parses as "20 seconds"
     *    "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
     *    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
     *    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
     *    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
     * </pre>
     *
     * @param text the text to parse, not null
     * @return the parsed duration, not null
     * @throws IllegalArgumentException if the text cannot be parsed to a duration
     */
    public static Duration parse(final CharSequence text) {
        Objects.requireNonNull(text, "text");
        final Matcher matcher = PATTERN.matcher(text);
        if (matcher.matches()) {
            // check for letter T but no time sections
            if ("T".equals(matcher.group(2)) == false) {
                final String dayMatch = matcher.group(1);
                final String hourMatch = matcher.group(3);
                final String minuteMatch = matcher.group(4);
                final String secondMatch = matcher.group(5);
                if (dayMatch != null || hourMatch != null || minuteMatch != null || secondMatch != null) {
                    final long daysAsSecs = parseNumber(text, dayMatch, SECONDS_PER_DAY, "days");
                    final long hoursAsSecs = parseNumber(text, hourMatch, SECONDS_PER_HOUR, "hours");
                    final long minsAsSecs = parseNumber(text, minuteMatch, SECONDS_PER_MINUTE, "minutes");
                    final long seconds = parseNumber(text, secondMatch, 1, "seconds");
                    try {
                        return create(daysAsSecs, hoursAsSecs, minsAsSecs, seconds);
                    } catch (final ArithmeticException ex) {
                        throw new IllegalArgumentException("Text cannot be parsed to a Duration (overflow) " + text, ex);
                    }
                }
            }
        }
        throw new IllegalArgumentException("Text cannot be parsed to a Duration: " + text);
    }

    private static long parseNumber(final CharSequence text, final String parsed, final int multiplier,
            final String errorText) {
        // regex limits to [0-9]+
        if (parsed == null) {
            return 0;
        }
        try {
            final long val = Long.parseLong(parsed);
            return val * multiplier;
        } catch (final Exception ex) {
            throw new IllegalArgumentException("Text cannot be parsed to a Duration: " + errorText + " (in " + text
                    + ")", ex);
        }
    }

    private static Duration create(final long daysAsSecs, final long hoursAsSecs, final long minsAsSecs, final long secs) {
        return create(daysAsSecs + hoursAsSecs + minsAsSecs + secs);
    }

    /**
     * Obtains an instance of {@code Duration} using seconds.
     *
     * @param seconds the length of the duration in seconds, positive only
     */
    private static Duration create(final long seconds) {
        if ((seconds) == 0) {
            return ZERO;
        }
        return new Duration(seconds);
    }

    /**
     * Converts this duration to the total length in milliseconds.
     *
     * @return the total length of the duration in milliseconds
     */
    public long toMillis() {
        return seconds * 1000L;
    }

    @Override
    public boolean equals(final Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof Duration)) {
            return false;
        }
        final Duration other = (Duration) obj;
        return other.seconds == this.seconds;
    }

    @Override
    public int hashCode() {
        return (int) (seconds ^ (seconds >>> 32));
    }

    /**
     * A string representation of this duration using ISO-8601 seconds based representation, such as {@code PT8H6M12S}.
     * <p>
     * The format of the returned string will be {@code PnDTnHnMnS}, where n is the relevant days, hours, minutes or
     * seconds part of the duration. If a section has a zero value, it is omitted. The hours, minutes and seconds are
     * all positive.
     * <p>
     * Examples:
     * 
     * <pre>
     *    "20 seconds"                     -- "PT20S
     *    "15 minutes" (15 * 60 seconds)   -- "PT15M"
     *    "10 hours" (10 * 3600 seconds)   -- "PT10H"
     *    "2 days" (2 * 86400 seconds)     -- "P2D"
     * </pre>
     * 
     * @return an ISO-8601 representation of this duration, not null
     */
    @Override
    public String toString() {
        if (this == ZERO) {
            return "PT0S";
        }
        final long days = seconds / SECONDS_PER_DAY;
        final long hours = (seconds % SECONDS_PER_DAY) / SECONDS_PER_HOUR;
        final int minutes = (int) ((seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);
        final int secs = (int) (seconds % SECONDS_PER_MINUTE);
        final StringBuilder buf = new StringBuilder(24);
        buf.append("P");
        if (days != 0) {
            buf.append(days).append('D');
        }
        if ((hours | minutes | secs) != 0) {
            buf.append('T');
        }
        if (hours != 0) {
            buf.append(hours).append('H');
        }
        if (minutes != 0) {
            buf.append(minutes).append('M');
        }
        if (secs == 0 && buf.length() > 0) {
            return buf.toString();
        }
        buf.append(secs).append('S');
        return buf.toString();
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    @Override
    public int compareTo(final Duration other) {
        return Long.signum(toMillis() - other.toMillis());
    }
}
