/*
 * 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.
 */

#ifndef _DECAF_UTIL_CONCURRENT_TIMEUNIT_H_
#define _DECAF_UTIL_CONCURRENT_TIMEUNIT_H_

#include <string>
#include <decaf/util/Config.h>
#include <decaf/lang/Comparable.h>
#include <decaf/util/concurrent/Synchronizable.h>
#include <decaf/lang/exceptions/IllegalArgumentException.h>
#include <decaf/lang/exceptions/InterruptedException.h>
#include <decaf/lang/exceptions/NullPointerException.h>

namespace decaf {
namespace lang {
    class Thread;
}
namespace util {
namespace concurrent {

    /**
     * A TimeUnit represents time durations at a given unit of granularity and
     * provides utility methods to convert across units, and to perform timing
     * and delay operations in these units. A TimeUnit does not maintain time
     * information, but only helps organize and use time representations that
     * may be maintained separately across various contexts. A nanosecond is
     * defined as one thousandth of a microsecond, a microsecond as one thousandth
     * of a millisecond, a millisecond as one thousandth of a second, a minute as
     * sixty seconds, an hour as sixty minutes, and a day as twenty four hours.
     *
     * A TimeUnit is mainly used to inform time-based methods how a given timing
     * parameter should be interpreted. For example, the following code will timeout
     * in 50 milliseconds if the lock is not available:
     *
     *  Lock lock = ...;
     *  if ( lock.tryLock( 50, TimeUnit.MILLISECONDS ) ) ...
     *
     * while this code will timeout in 50 seconds:
     *
     *  Lock lock = ...;
     *  if ( lock.tryLock( 50, TimeUnit.SECONDS ) ) ...
     *
     * Note however, that there is no guarantee that a particular timeout implementation
     * will be able to notice the passage of time at the same granularity as the given
     * TimeUnit.
     */
    class DECAF_API TimeUnit : public decaf::lang::Comparable<TimeUnit> {
    private:

        /** This TimeUnit's index */
        int index;

        /** Name of the Unit being represented. */
        std::string name;

        /** Array of Time Unit multipliers */
        static const long long multipliers[];

    public:

        /** The Actual TimeUnit enumerations */
        static const TimeUnit NANOSECONDS;
        static const TimeUnit MICROSECONDS;
        static const TimeUnit MILLISECONDS;
        static const TimeUnit SECONDS;
        static const TimeUnit MINUTES;
        static const TimeUnit HOURS;
        static const TimeUnit DAYS;

        /** The An Array of TimeUnit Instances */
        static const TimeUnit* const values[];

    protected:

        /**
         * Hidden Constructor, this class can not be instantiated directly.
         * @param index - Index into the Time Unit set.
         * @param name - Name of the unit type being represented.
         */
        TimeUnit( int index, const std::string& name );

    public:

        virtual ~TimeUnit() {}

        /**
         * Convert the given time duration in the given unit to this unit. Conversions
         * from finer to coarser granularities truncate, so lose precision. For example
         * converting 999 milliseconds to seconds results in 0. Conversions from coarser
         * to finer granularities with arguments that would numerically overflow saturate
         * to Long.MIN_VALUE if negative or Long.MAX_VALUE if positive.
         * <p>
         * For example, to convert 10 minutes to milliseconds, use:
         * TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)
         * <p>
         * @param sourceDuration - Duration value to convert.
         * @param sourceUnit - Unit type of the source duration.
         * @return the converted duration in this unit, or Long.MIN_VALUE if conversion
         * would negatively overflow, or Long.MAX_VALUE if it would positively overflow.
         */
        long long convert( long long sourceDuration, const TimeUnit& sourceUnit ) const;

        /**
         * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
         * @param duration the duration
         * @return the converted duration,
         * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
         * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
         * @see #convert
         */
        long long toNanos( long long duration ) const {
            return doConvert( this->index, NANOSECONDS.index, duration );
        }

        /**
         * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
         * @param duration the duration
         * @return the converted duration,
         * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
         * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
         * @see #convert
         */
        long long toMicros( long long duration ) const {
            return doConvert( this->index, MICROSECONDS.index, duration );
        }

        /**
         * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
         * @param duration the duration
         * @return the converted duration,
         * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
         * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
         * @see #convert
         */
        long long toMillis( long long duration ) const {
            return doConvert( this->index, MILLISECONDS.index, duration );
        }

        /**
         * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
         * @param duration the duration
         * @return the converted duration.
         * @see #convert
         */
        long long toSeconds( long long duration ) const {
            return doConvert( this->index, SECONDS.index, duration );
        }

        /**
         * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
         * @param duration the duration
         * @return the converted duration.
         * @see #convert
         */
        long long toMinutes( long long duration ) const {
            return doConvert( this->index, MINUTES.index, duration );
        }

        /**
         * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
         * @param duration the duration
         * @return the converted duration.
         * @see #convert
         */
        long long toHours( long long duration ) const {
            return doConvert( this->index, HOURS.index, duration );
        }

        /**
         * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
         * @param duration the duration
         * @return the converted duration.
         * @see #convert
         */
        long long toDays( long long duration ) const {
            return doConvert( this->index, DAYS.index, duration );
        }

        /**
         * Perform a timed <tt>Object.wait</tt> using this time unit.
         * This is a convenience method that converts timeout arguments
         * into the form required by the <tt>Object.wait</tt> method.
         *
         * <p>For example, you could implement a blocking <tt>poll</tt>
         * method (see {@link BlockingQueue#poll BlockingQueue.poll})
         * using:
         *
         * <pre>
         *    Object poll( long long timeout, const TimeUnit& unit )
         *
         *      while( empty ) {
         *        unit.timedWait(this, timeout);
         *        ...
         *      }
         *  }</pre>
         *
         * @param obj the object to wait on
         * @param timeout the maximum time to wait.
         *
         * @throws InterruptedException if interrupted while waiting.
         * @throws NullPointerException if the Synchronizable object is null.
         *
         * @see Synchronizable#wait( long long, long long )
         */
        void timedWait( Synchronizable* obj, long long timeout ) const;

        /**
         * Perform a timed <tt>Thread.join</tt> using this time unit.
         * This is a convenience method that converts time arguments into the
         * form required by the <tt>Thread.join</tt> method.
         *
         * @param thread the thread to wait for
         * @param timeout the maximum time to wait
         *
         * @throws InterruptedException if interrupted while waiting.
         * @throws NullPointerException if the thread object is null.
         *
         * @see Thread#join( long long, long long )
         */
        void timedJoin( decaf::lang::Thread* thread, long long timeout );

        /**
         * Perform a <tt>Thread.sleep</tt> using this unit.
         * This is a convenience method that converts time arguments into the
         * form required by the <tt>Thread.sleep</tt> method.
         * @param timeout the minimum time to sleep
         * @see Thread#sleep
         */
        void sleep( long long timeout ) const;

        /**
         * Converts the TimeUnit type to the Name of the TimeUnit.
         * @return String name of the TimeUnit
         */
        virtual std::string toString() const;

    public:  // Static Methods

        /**
         * Returns the TimeUnit constant of this type with the specified name. The
         * string must match exactly an identifier used to declare an TimeUnit constant
         * in this type. (Extraneous whitespace characters are not permitted.)
         *
         * @param name
         *          The Name of the TimeUnit constant to be returned.
         * @return
         *          A constant reference to the TimeUnit Constant with the given name.
         * @throws IllegalArgumentException
         *          if this enum type has no constant with the specified name
         */
        static const TimeUnit& valueOf( const std::string& name );

    public:

        virtual int compareTo( const TimeUnit& value ) const;

        virtual bool equals( const TimeUnit& value ) const;

        virtual bool operator==( const TimeUnit& value ) const;

        virtual bool operator<( const TimeUnit& value ) const;

    private:

        /* Perform the actual conversion */
        long long doConvert( int srcIndex, int destIndex, long long duration ) const;

        /*
         * Utility method to compute the excess-nanosecond argument to
         * wait, sleep, join.
         */
        int excessNanos( long long time, long long ms ) const;

        /**
         * Scale d by m, checking for overflow.
         * @param duration - The amount of time to scale by the multiplier.
         * @param multiplier - The scaling factor.
         * @param overflow - The value at which d * m would cause an overflow.
         */
        static long long scale( long long duration, long long multiplier, long long overflow );

    };

}}}

#endif /*_DECAF_UTIL_CONCURRENT_TIMEUNIT_H_*/
