/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.xmlbeans;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;

/**
 * Used to build {@link GDuration GDurations}.
 */
public class GDurationBuilder implements GDurationSpecification, java.io.Serializable {
    private static final long serialVersionUID = 1L;

    private int _sign;
    private int _CY;
    private int _M;
    private int _D;
    private int _h;
    private int _m;
    private int _s;
    private BigDecimal _fs;

    /**
     * Constructs an empty GDurationBuilder representing zero seconds.
     */
    public GDurationBuilder() {
        _sign = +1;
        _fs = GDate._zero;
    }

    /**
     * Constructs a GDuration from a lexical
     * representation.
     */
    public GDurationBuilder(String s) {
        this(new GDuration(s));
    }

    /**
     * Constructs a GDurationBuilder with the specified sign,
     * year, month, day, hours, minutes, seconds, and optional
     * fractional seconds.
     *
     * @param sign +1 for a positive duration, -1 for a negative duration
     * @throws java.lang.IllegalArgumentException if the sign is not 1 or -1
     */
    public GDurationBuilder(
        int sign,
        int year,
        int month,
        int day,
        int hour,
        int minute,
        int second,
        BigDecimal fraction) {
        if (sign != 1 && sign != -1) {
            throw new IllegalArgumentException();
        }
        _sign = sign;
        _CY = year;
        _M = month;
        _D = day;
        _h = hour;
        _m = minute;
        _s = second;
        _fs = fraction == null ? GDate._zero : fraction;
    }

    /**
     * Constructs a GDurationBuilder from another GDurationBuilderSpecification.
     */
    public GDurationBuilder(GDurationSpecification gDuration) {
        _sign = gDuration.getSign();
        _CY = gDuration.getYear();
        _M = gDuration.getMonth();
        _D = gDuration.getDay();
        _h = gDuration.getHour();
        _m = gDuration.getMinute();
        _s = gDuration.getSecond();
        _fs = gDuration.getFraction();
    }

    /**
     * Builds another GDurationBuilder with the same value
     * as this one.
     */
    public Object clone() {
        return new GDurationBuilder(this);
    }

    /**
     * Builds a GDuration from this GDurationBuilder.
     */
    public GDuration toGDuration() {
        return new GDuration(this);
    }

    /**
     * Adds to this duration.  Does a fieldwise add, with no
     * normalization.
     */
    public void addGDuration(GDurationSpecification duration) {
        int sign = _sign * duration.getSign();
        _add(duration, sign);
    }

    /**
     * Subtracts from this duration.  Does a fieldwise subtraction,
     * with no normalization.
     */
    public void subtractGDuration(GDurationSpecification duration) {
        int sign = -_sign * duration.getSign();
        _add(duration, sign);
    }

    private void _add(GDurationSpecification duration, int sign) {
        _CY += sign * duration.getYear();
        _M += sign * duration.getMonth();
        _D += sign * duration.getDay();
        _h += sign * duration.getHour();
        _m += sign * duration.getMinute();
        _s += sign * duration.getSecond();

        if (duration.getFraction().signum() == 0) {
            return;
        }

        if (_fs.signum() == 0 && sign == 1) {
            _fs = duration.getFraction();
        } else {
            _fs = sign > 0 ?
                _fs.add(duration.getFraction()) :
                _fs.subtract(duration.getFraction());
        }
    }

    /**
     * Sets the sign.
     */
    public final void setSign(int sign) {
        if (sign != 1 && sign != -1) {
            throw new IllegalArgumentException();
        }
        _sign = sign;
    }

    /**
     * Sets the year component.
     */
    public void setYear(int year) {
        _CY = year;
    }

    /**
     * Sets the month component.
     */
    public void setMonth(int month) {
        _M = month;
    }

    /**
     * Sets the day component.
     */
    public void setDay(int day) {
        _D = day;
    }

    /**
     * Sets the hour component.
     */
    public void setHour(int hour) {
        _h = hour;
    }

    /**
     * Sets the minute component.
     */
    public void setMinute(int minute) {
        _m = minute;
    }

    /**
     * Sets the second component.
     */
    public void setSecond(int second) {
        _s = second;
    }

    /**
     * Sets the fraction-of-second component.
     */
    public void setFraction(BigDecimal fraction) {
        _fs = fraction == null ? GDate._zero : fraction;
    }

    /**
     * All GDuration instances return true.
     */
    public final boolean isImmutable() {
        return true;
    }

    /**
     * Returns the sign of the duration: +1 is forwards
     * and -1 is backwards in time.
     * This value does not necessarily reflect the
     * true direction of the duration if the duration
     * is not normalized or not normalizable.
     */
    public final int getSign() {
        return _sign;
    }

    /**
     * Gets the year component.
     */
    public final int getYear() {
        return _CY;
    }

    /**
     * Gets the month-of-year component.
     */
    public final int getMonth() {
        return _M;
    }

    /**
     * Gets the day-of-month component.
     */
    public final int getDay() {
        return _D;
    }

    /**
     * Gets the hour-of-day component.
     */
    public final int getHour() {
        return _h;
    }

    /**
     * Gets the minute-of-hour component.
     */
    public final int getMinute() {
        return _m;
    }

    /**
     * Gets the second-of-minute component.
     */
    public final int getSecond() {
        return _s;
    }


    /**
     * Gets the fraction-of-second. Range from 0 (inclusive) to 1 (exclusive).
     */
    public BigDecimal getFraction() {
        return _fs;
    }

    /**
     * Returns true if all of the individual components
     * of the duration are nonnegative.
     */
    public boolean isValid() {
        return GDurationBuilder.isValidDuration(this);
    }


    /**
     * Normalize a duration value. This ensures that months,
     * hours, minutes, seconds, and fractions are positive and
     * within the ranges 0..11, 0..23, 0..59, etc. Negative
     * durations are indicated by a negative sign rather
     * than negative components.
     * <p>
     * Most duration specifications can be normalized to
     * valid durations with all positive components, but
     * not all of them can.
     * <p>
     * The only situations which cannot be normalized are
     * where the year/month and the day/hour/minute/second
     * offsets are of opposite sign. Days cannot be carried
     * into months since the length of a Gregorian month is
     * variable depending on when the duration is applied.
     * In these cases, this method normalizes the components
     * so that "day" is the only negative component.
     */
    public void normalize() {
        _normalizeImpl(true);
    }

    /**
     * fQuotient(a, b) = the greatest integer less than or equal to a/b
     */
    private static long _fQuotient(long a, int b) {
        if ((a < 0) == (b < 0)) {
            return a / b;
        }

        return -((b - a - 1) / b);
    }

    /**
     * modulo(a, b) = a - fQuotient(a,b)*b
     */
    private static int _mod(long a, int b, long quotient) {
        return (int) (a - quotient * b);
    }


    /**
     * Private implemenation of normalize. The flag is
     * to facilitate this method calling itself without
     * danger of infinite recursion.
     */
    private void _normalizeImpl(boolean adjustSign) {
        long temp;

        // months to years
        if (_M < 0 || _M > 11) {
            temp = _M;
            long ycarry = _fQuotient(temp, 12);
            _M = _mod(temp, 12, ycarry);
            _CY += ycarry;
        }

        long carry = 0;

        // fractions to seconds
        if (_fs != null && (_fs.signum() < 0 || _fs.compareTo(GDate._one) >= 0)) {
            BigDecimal bdcarry = _fs.setScale(0, RoundingMode.FLOOR);
            _fs = _fs.subtract(bdcarry);
            carry = bdcarry.intValue();
        }

        if (carry != 0 || _s < 0 || _s > 59 || _m < 0 || _m > 50 || _h < 0 || _h > 23) {
            // seconds
            temp = _s + carry;
            carry = _fQuotient(temp, 60);
            _s = _mod(temp, 60, carry);

            // minutes
            temp = _m + carry;
            carry = _fQuotient(temp, 60);
            _m = _mod(temp, 60, carry);

            // hours
            temp = _h + carry;
            carry = _fQuotient(temp, 24);
            _h = _mod(temp, 24, carry);
            _D += carry;
        }

        if (_CY == 0 && _M == 0 && _D == 0 && _h == 0 && _m == 0 && _s == 0 && (_fs == null || _fs.signum() == 0)) {
            _sign = 1;
        }

        if (adjustSign && (_D < 0 || _CY < 0)) {
            int sign = (_D <= 0 && (_CY < 0 || _CY == 0 && _M == 0)) ? -_sign : _getTotalSignSlowly();
            if (sign == 2) {
                sign = (_CY < 0) ? -_sign : _sign;
            }
            if (sign == 0) {
                sign = 1;
            }
            if (sign != _sign) {
                _sign = sign;
                _CY = -_CY;
                _M = -_M;
                _D = -_D;
                _h = -_h;
                _m = -_m;
                _s = -_s;
                if (_fs != null) {
                    _fs = _fs.negate();
                }
            }
            _normalizeImpl(false);
        }
    }


    /* package */
    static boolean isValidDuration(GDurationSpecification spec) {
        if (!(spec.getSign() == 1 || spec.getSign() == -1)) {
            return false;
        }

        return (spec.getYear() >= 0 && spec.getMonth() >= 0 && spec.getDay() >= 0 &&
                spec.getHour() >= 0 && spec.getMinute() >= 0 && spec.getSecond() >= 0 &&
                spec.getFraction().signum() >= 0);
    }

    /**
     * Comparison to another GDuration.
     * <ul>
     * <li>Returns -1 if this < duration. (less-than)
     * <li>Returns 0 if this == duration. (equal)
     * <li>Returns 1 if this > duration. (greater-than)
     * <li>Returns 2 if this <> duration. (incomparable)
     * </ul>
     * Two instances are incomparable if they have different amounts
     * of information.
     */
    public final int compareToGDuration(GDurationSpecification duration) {
        return GDurationBuilder.compareDurations(this, duration);
    }

    /**
     * The natural string representation of the duration.
     * <p>
     * Any components that are zero are omitted. Note that if the duration
     * is invalid, i.e., it has negative components, those negative
     * components are serialized out here. To check for validity, use
     * the isValid() method; and to normalize most durations to a valid
     * form use the normalize() method.
     */
    public String toString() {
        return GDurationBuilder.formatDuration(this);
    }

    /* package */
    static int compareDurations(GDurationSpecification d1, GDurationSpecification d2) {
        // first do an all-fields check
        if (d1.getFraction().signum() == 0 && d2.getFraction().signum() == 0) {
            int s1 = d1.getSign();
            int s2 = d2.getSign();
            long month1 = s1 * ((long) d1.getYear() * 12 + d1.getMonth());
            long month2 = s2 * ((long) d2.getYear() * 12 + d2.getMonth());
            long sec1 = s1 * ((((long) d1.getDay() * 24 + d1.getHour()) * 60 + d1.getMinute()) * 60 + d1.getSecond());
            long sec2 = s2 * ((((long) d2.getDay() * 24 + d2.getHour()) * 60 + d2.getMinute()) * 60 + d2.getSecond());
            if (month1 == month2) {
                if (sec1 == sec2) {
                    return 0;
                }
                return sec1 < sec2 ? -1 : 1;
            }
            if (month1 < month2 && sec1 - sec2 < 28 * 24 * 60 * 60) {
                return -1;
            }
            if (month1 > month2 && sec2 - sec1 < 28 * 24 * 60 * 60) {
                return 1;
            }
        }

        // the answer isn't obvious, so then do a total-sign check
        GDurationBuilder diff = new GDurationBuilder(d1);
        diff.subtractGDuration(d2);
        return diff._getTotalSignSlowly();
    }

    /**
     * Per schema spec, comparison of durations is simply done
     * by calculating adding the duration to these four dates and
     * comparing the results. If the results are ambiguous, the
     * answer is "incomparable".
     */
    private static final GDate[] _compDate = new GDate[]
        {
            new GDate(1696, 9, 1, 0, 0, 0, null, 0, 0, 0),
            new GDate(1697, 2, 1, 0, 0, 0, null, 0, 0, 0),
            new GDate(1903, 3, 1, 0, 0, 0, null, 0, 0, 0),
            new GDate(1903, 7, 1, 0, 0, 0, null, 0, 0, 0)
        };


    /**
     * This returns the total sign of the duration, +1
     * if the duration moves forward in time, -1 if the
     * duration moves backwards in time, 0 if the duration
     * is zero-length, and 2 if the duration may be positive
     * or negative depending on the date.
     * <p>
     * (For example, one month minus 30 days is indeterminate).
     */
    private int _getTotalSignSlowly() {
        int pos = 0;
        int neg = 0;
        int zer = 0;

        GDateBuilder enddate = new GDateBuilder();
        for (GDate gDate : _compDate) {
            enddate.setGDate(gDate);
            enddate.addGDuration(this);
            switch (enddate.compareToGDate(gDate)) {
                case -1:
                    neg++;
                    break;
                case 0:
                    zer++;
                    break;
                case 1:
                    pos++;
                    break;
            }
        }

        if (pos == _compDate.length) {
            return +1;
        }
        if (neg == _compDate.length) {
            return -1;
        }
        if (zer == _compDate.length) {
            return 0;
        }
        return 2;
    }

    /* package */
    static String formatDuration(GDurationSpecification duration) {
        // Sign+P:      (-)?P
        // Year:        (?:(\d+)Y)?
        // Month:       (?:(\d+)M)?
        // Day:         (?:(\d+)D)?
        // Time:        (?:(T)
        // Hours:          (?:(\d+)H)?
        // Minutes:        (?:(\d+)M)?
        // Seconds:        (?:(\d+(?:\.\d*)?|(?:.\d+)S)?

        StringBuilder message = new StringBuilder(30);

        if (duration.getSign() < 0) {
            message.append('-');
        }

        message.append('P');

        if (duration.getYear() != 0) {
            message.append(duration.getYear());
            message.append('Y');
        }

        if (duration.getMonth() != 0) {
            message.append(duration.getMonth());
            message.append('M');
        }

        if (duration.getDay() != 0) {
            message.append(duration.getDay());
            message.append('D');
        }

        if (duration.getHour() != 0 || duration.getMinute() != 0 || duration.getSecond() != 0 ||
            (duration.getFraction().signum() != 0)) {
            message.append('T');
        }

        if (duration.getHour() != 0) {
            message.append(duration.getHour());
            message.append('H');
        }

        if (duration.getMinute() != 0) {
            message.append(duration.getMinute());
            message.append('M');
        }

        if (duration.getFraction().signum() != 0) {
            BigDecimal s = duration.getFraction();
            if (duration.getSecond() != 0) {
                s = s.add(BigDecimal.valueOf(duration.getSecond()));
            }
            // todo when upgrade to 1.5  message.append(s.stripTrailingZeros().toPlainString());
            message.append(stripTrailingZeros(toPlainString(s)));
            message.append('S');
        } else if (duration.getSecond() != 0) {
            message.append(duration.getSecond());
            message.append('S');
        } else if (message.length() <= 2)
        // Specify zero seconds if everything was 0
        {
            message.append("T0S");
        }

        return message.toString();
    }

    public static String toPlainString(BigDecimal bd) {
        BigInteger intVal = bd.unscaledValue();
        int scale = bd.scale();
        String intValStr = intVal.toString();
        if (scale == 0) {
            return intValStr;
        }

        boolean isNegative = (intValStr.charAt(0) == '-');

        int point = intValStr.length() - scale - (isNegative ? 1 : 0);

        StringBuilder sb = new StringBuilder(intValStr.length() + 2 + (point <= 0 ? (-point + 1) : 0));
        if (point <= 0) {
            // prepend zeros and a decimal point.
            if (isNegative) {
                sb.append('-');
            }
            sb.append('0').append('.');
            while (point < 0) {
                sb.append('0');
                point++;
            }
            sb.append(intValStr.substring(isNegative ? 1 : 0));
        } else if (point < intValStr.length()) {
            // No zeros needed
            sb.append(intValStr);
            sb.insert(point + (isNegative ? 1 : 0), '.');
        } else {
            // append zeros if not 0
            sb.append(intValStr);
            if (!intVal.equals(BigInteger.ZERO)) {
                for (int i = intValStr.length(); i < point; i++) {
                    sb.append('0');
                }
            }
        }
        return sb.toString();
    }

    public static String stripTrailingZeros(String s) {
        boolean seenDot = false;
        int i = s.length() - 1;
        int zeroIndex = i;

        while (i >= 0) {
            if (s.charAt(i) != '0') {
                break;
            }
            i--;
            zeroIndex--;
        }
        while (i >= 0) {
            if (s.charAt(i) == 'E') {
                return s;
            }
            if (s.charAt(i) == '.') {
                seenDot = true;
                break;
            }
            i--;
        }

        return seenDot ? s.substring(0, zeroIndex + 1) : s;
    }
}
