/*
 * 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_IO_INPUTSTREAM_H_
#define _DECAF_IO_INPUTSTREAM_H_

#include <decaf/io/IOException.h>
#include <decaf/io/Closeable.h>
#include <decaf/util/concurrent/Synchronizable.h>
#include <decaf/util/concurrent/Mutex.h>
#include <decaf/lang/exceptions/UnsupportedOperationException.h>
#include <decaf/lang/exceptions/NullPointerException.h>
#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
#include <decaf/util/Config.h>

namespace decaf{
namespace io{

    /**
     * A base class that must be implemented by all classes wishing to provide a
     * class that reads in a stream of bytes
     *
     * @since 1.0
     */
    class DECAF_API InputStream: public Closeable, virtual public util::concurrent::Synchronizable {
    private:

        // Synchronization object.
        util::concurrent::Mutex mutex;

    private:

        InputStream(const InputStream&);
        InputStream& operator=(const InputStream&);

    public:

        InputStream();

        virtual ~InputStream();

        /**
         * Closes the InputStream freeing any resources that might have been acquired
         * during the lifetime of this stream.
         *
         * The default implementation of this method does nothing.
         *
         * @throws IOException if an I/O error occurs while closing the InputStream.
         */
        virtual void close();

        /**
         * Marks the current position in the stream A subsequent call to the
         * reset method repositions this stream at the last marked position so
         * that subsequent reads re-read the same bytes.
         *
         * If a stream instance reports that marks are supported then the stream
         * will ensure that the same bytes can be read again after the reset method
         * is called so long the readLimit is not reached.
         *
         * Calling mark on a closed stream instance should have no effect.
         *
         * The default implementation of this method does nothing.
         *
         * @param readLimit
         *      The max bytes read before marked position is invalid.
         */
        virtual void mark(int readLimit);

        /**
         * Repositions this stream to the position at the time the mark method was
         * last called on this input stream.
         *
         * If the method markSupported returns true, then:
         *   * If the method mark has not been called since the stream was created,
         *     or the number of bytes read from the stream since mark was last called
         * 	   is larger than the argument to mark at that last call, then an
         *     IOException might be thrown.
         *   * If such an IOException is not thrown, then the stream is reset to a
         *     state such that all the bytes read since the most recent call to mark
         *     (or since the start of the file, if mark has not been called) will be
         *     resupplied to subsequent callers of the read method, followed by any
         *     bytes that otherwise would have been the next input data as of the
         *     time of the call to reset.
         *
         * If the method markSupported returns false, then:
         *   * The call to reset may throw an IOException.
         *   * If an IOException is not thrown, then the stream is reset to a fixed
         *     state that depends on the particular type of the input stream and how
         *     it was created. The bytes that will be supplied to subsequent callers
         *     of the read method depend on the particular type of the input stream.
         *
         * The default implementation of this method throws an IOException.
         *
         * @throws IOException if an I/O error occurs.
         */
        virtual void reset();

        /**
         * Determines if this input stream supports the mark and reset methods.
         * Whether or not mark and reset are supported is an invariant property of
         * a particular input stream instance.
         *
         * The default implementation of this method returns false.
         *
         * @return true if this stream instance supports marks
         */
        virtual bool markSupported() const {
            return false;
        }

        /**
         * Indicates the number of bytes available.  The default implementation of this
         * methods returns 0.  Classes that override this method may return the total
         * number of bytes that are currently available for reading and others may simply
         * return a value of one indicating that there is some data avaiable.  The caller
         * should view the result of this method as an absolute.
         *
         * The default implementation of this method returns zero.
         *
         * @return the number of bytes available on this input stream.
         *
         * @throws IOException if an I/O error occurs.
         */
        virtual int available() const {
            return 0;
        }

        /**
         * Reads a single byte from the buffer.  The value byte is returned as an int in the
         * range 0 to 255. If no byte is available because the end of the stream has been reached,
         * the value -1 is returned. This method blocks until input data is available, the end of
         * the stream is detected, or an exception is thrown.
         *
         * The default implementation of this method calls the internal virtual method doReadByte
         * which is a pure virtual method and must be overridden by all subclasses.
         *
         * @return The next byte or -1 if the end of stream is reached.
         *
         * @throws IOException if an I/O error occurs.
         */
        virtual int read();

        /**
         * Reads up to size bytes of data from the input stream into an array of bytes. An
         * attempt is made to read as many as size bytes, but a smaller number may be read.
         * The number of bytes actually read is returned as an integer.
         *
         * This method blocks until input data is available, end of file is detected, or
         * an exception is thrown.
         *
         * If size is zero, then no bytes are read and 0 is returned; otherwise, there is an
         * attempt to read at least one byte. If no byte is available because the stream is
         * at end of file, the value -1 is returned; otherwise, at least one byte is read and
         * stored into b.
         *
         * This method called the protected virtual method doReadArray which by default is the
         * same as calling read( buffer, size, 0, size ).  Subclasses can customize the behavior
         * of this method by overriding the doReadArray method to provide a better performing
         * read operation.
         *
         * @param buffer
         *      The target buffer to write the read in data to.
         * @param size
         *      The size in bytes of the target buffer.
         *
         * @return The number of bytes read or -1 if EOF is detected
         *
         * @throws IOException if an I/O error occurs.
         * @throws NullPointerException if buffer passed is NULL.
         */
        virtual int read(unsigned char* buffer, int size);

        /**
         * Reads up to length bytes of data from the input stream into an array of bytes. An
         * attempt is made to read as many as length bytes, but a smaller number may be read.
         * The number of bytes actually read is returned as an integer.
         *
         * This method blocks until input data is available, end of file is detected, or
         * an exception is thrown.
         *
         * If length is zero, then no bytes are read and 0 is returned; otherwise, there is an
         * attempt to read at least one byte. If no byte is available because the stream is
         * at end of file, the value -1 is returned; otherwise, at least one byte is read and
         * stored into b.
         *
         * The first byte read is stored into element b[off], the next one into b[off+1], and
         * so on. The number of bytes read is, at most, equal to length. Let k be the number of
         * bytes actually read; these bytes will be stored in elements b[off] through b[off+k-1],
         * leaving elements b[offset+k] through b[offset+length-1] unaffected.
         *
         * In every case, elements b[0] through b[offset] and elements b[offset+length] through
         * b[b.length-1] are unaffected.
         *
         * This method called the protected virtual method doReadArrayBounded which simply
         * calls the method doReadByte() repeatedly. If the first such call results in an IOException,
         * that exception is returned. If any subsequent call to doReadByte() results in a IOException,
         * the exception is caught and treated as if it were end of file; the bytes read up to that
         * point are stored into the buffer and the number of bytes read before the exception occurred
         * is returned. The default implementation of this method blocks until the requested amount of
         * input data has been read, end of file is detected, or an exception is thrown. Subclasses
         * are encouraged to provide a more efficient implementation of this method.
         *
         * @param buffer
         *      The target buffer to write the read in data to.
         * @param size
         *      The size in bytes of the target buffer.
         * @param offset
         *      The position in the buffer to start inserting the read in data.
         * @param length
         *      The maximum number of bytes that should be read into buffer.
         *
         * @return The number of bytes read or -1 if EOF is detected
         *
         * @throws IOException if an I/O error occurs.
         * @throws NullPointerException if buffer passed is NULL.
         * @throws IndexOutOfBoundsException if length > size - offset.
         */
        virtual int read(unsigned char* buffer, int size, int offset, int length);

        /**
         * Skips over and discards n bytes of data from this input stream. The skip
         * method may, for a variety of reasons, end up skipping over some smaller
         * number of bytes, possibly 0. This may result from any of a number of
         * conditions; reaching end of file before n bytes have been skipped is
         * only one possibility. The actual number of bytes skipped is returned.
         *
         * The skip method of InputStream creates a byte array and then repeatedly
         * reads into it until num bytes have been read or the end of the stream has
         * been reached. Subclasses are encouraged to provide a more efficient
         * implementation of this method.
         *
         * @param num
         *       The number of bytes to skip.
         *
         * @return total bytes skipped
         *
         * @throws IOException if an I/O error occurs.
         * @throws UnsupportedOperationException if the concrete stream class does
         *         not support skipping bytes.
         */
        virtual long long skip(long long num);

        /**
         * Output a String representation of this object.
         *
         * The default version of this method just prints the Class Name.
         *
         * @return a string representation of the object.
         */
        virtual std::string toString() const;

    protected: // Virtual doRead methods that can be overridden to customize subclasses.

        virtual int doReadByte() = 0;

        virtual int doReadArray(unsigned char* buffer, int size);

        virtual int doReadArrayBounded(unsigned char* buffer, int size, int offset, int length);

    public: // Synchronizable

        virtual void lock() {
            mutex.lock();
        }

        virtual bool tryLock() {
            return mutex.tryLock();
        }

        virtual void unlock() {
            mutex.unlock();
        }

        virtual void wait() {
            mutex.wait();
        }

        virtual void wait(long long millisecs) {
            mutex.wait(millisecs);
        }

        virtual void wait(long long millisecs, int nanos) {
            mutex.wait(millisecs, nanos);
        }

        virtual void notify() {
            mutex.notify();
        }

        virtual void notifyAll() {
            mutex.notifyAll();
        }

    };

}}

#endif /*_DECAF_IO_INPUTSTREAM_H_*/
