/*
 * 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_UTI_ZIP_INFLATER_H_
#define _DECAF_UTI_ZIP_INFLATER_H_

#include <decaf/util/Config.h>

#include <decaf/lang/exceptions/NullPointerException.h>
#include <decaf/lang/exceptions/IllegalArgumentException.h>
#include <decaf/lang/exceptions/IllegalStateException.h>
#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>

#include <decaf/util/zip/DataFormatException.h>

#include <vector>

namespace decaf {
namespace util {
namespace zip {

    class InflaterData;

    /**
     * This class uncompresses data that was compressed using the <i>DEFLATE</i>
     * algorithm (see <a href="http://www.gzip.org/algorithm.txt">specification</a>).
     * <p>
     * Basically this class is part of the API to the stream based ZLIB compression
     * library and is used as such by InflaterInputStream and its descendants.
     * <p>
     * The typical usage of a Inflater outside this package consists of a specific
     * call to one of its constructors before being passed to an instance of
     * InflaterInputStream.
     *
     * @see InflaterInputStream
     * @see Deflater
     *
     * @since 1.0
     */
    class DECAF_API Inflater {
    private:

        InflaterData* data;

    private:

        Inflater(const Inflater&);
        Inflater& operator=(const Inflater&);

    public:

        /**
         * Creates a new decompressor.  This constructor defaults the inflater to use the ZLIB
         * header and checksum fields.
         */
        Inflater();

        /**
         * Creates a new decompressor. If the parameter 'nowrap' is true then the ZLIB header
         * and checksum fields will not be used. This provides compatibility with the compression
         * format used by both GZIP and PKZIP.
         *
         * Note: When using the 'nowrap' option it is also necessary to provide an extra "dummy"
         * byte as input. This is required by the ZLIB native library in order to support
         * certain optimizations.
         */
        Inflater(bool nowrap);

        virtual ~Inflater();

        /**
         * Sets input data for decompression. This should be called whenever needsInput() returns
         * true indicating that more input data is required.
         *
         * @param buffer
         *      The Buffer to read in for decompression.
         * @param size
         *      The size of the buffer passed in.
         * @param offset
         *      The position in the Buffer to start reading from.
         * @param length
         *      The number of bytes to read from the input buffer.
         *
         * @throws NullPointerException if buffer is NULL.
         * @throws IndexOutOfBoundsException if the offset + length > size of the buffer.
         * @throws IllegalStateException if in the end state.
         */
        void setInput(const unsigned char* buffer, int size, int offset, int length);

        /**
         * Sets input data for decompression. This should be called whenever needsInput() returns
         * true indicating that more input data is required.
         *
         * @param buffer
         *      The Buffer to read in for decompression.
         * @param offset
         *      The position in the Buffer to start reading from.
         * @param length
         *      The number of bytes to read from the input buffer.
         *
         * @throws IndexOutOfBoundsException if the offset + length > size of the buffer.
         * @throws IllegalStateException if in the end state.
         */
        void setInput(const std::vector<unsigned char>& buffer, int offset, int length);

        /**
         * Sets input data for decompression. This should be called whenever needsInput() returns
         * true indicating that more input data is required.
         *
         * @param buffer
         *      The Buffer to read in for decompression.
         *
         * @throws IllegalStateException if in the end state.
         */
        void setInput(const std::vector<unsigned char>& buffer);

        /**
         * Returns the total number of bytes remaining in the input buffer. This can be used to
         * find out what bytes still remain in the input buffer after decompression has finished.
         *
         * @return the total number of bytes remaining in the input buffer
         */
        int getRemaining() const;

        /**
         * Sets the preset dictionary to the given array of bytes. Should be called when inflate()
         * returns 0 and needsDictionary() returns true indicating that a preset dictionary is
         * required. The method getAdler() can be used to get the Adler-32 value of the dictionary
         * needed.
         *
         * @param buffer
         *      The Buffer to read in for decompression.
         * @param size
         *      The size of the buffer passed in.
         * @param offset
         *      The position in the Buffer to start reading from.
         * @param length
         *      The number of bytes to read from the input buffer.
         *
         * @throws NullPointerException if buffer is NULL.
         * @throws IndexOutOfBoundsException if the offset + length > size of the buffer.
         * @throws IllegalStateException if in the end state.
         * @throws IllegalArgumentException if the given dictionary doesn't match thre required
         *         dictionaries checksum value.
         */
        void setDictionary(const unsigned char* buffer, int size, int offset, int length);

        /**
         * Sets the preset dictionary to the given array of bytes. Should be called when inflate()
         * returns 0 and needsDictionary() returns true indicating that a preset dictionary is
         * required. The method getAdler() can be used to get the Adler-32 value of the dictionary
         * needed.
         *
         * @param buffer
         *      The Buffer to read in for decompression.
         * @param offset
         *      The position in the Buffer to start reading from.
         * @param length
         *      The number of bytes to read from the input buffer.
         *
         * @throws IndexOutOfBoundsException if the offset + length > size of the buffer.
         * @throws IllegalStateException if in the end state.
         * @throws IllegalArgumentException if the given dictionary doesn't match thre required
         *         dictionaries checksum value.
         */
        void setDictionary(const std::vector<unsigned char>& buffer, int offset, int length);

        /**
         * Sets the preset dictionary to the given array of bytes. Should be called when inflate()
         * returns 0 and needsDictionary() returns true indicating that a preset dictionary is
         * required. The method getAdler() can be used to get the Adler-32 value of the dictionary
         * needed.
         *
         * @param buffer
         *      The Buffer to read in for decompression.
         *
         * @throws IllegalStateException if in the end state.
         * @throws IllegalArgumentException if the given dictionary doesn't match the required
         *         dictionaries checksum value.
         */
        void setDictionary(const std::vector<unsigned char>& buffer);

        /**
         * @return true if the input data buffer is empty and setInput() should be called in
         *         order to provide more input
         */
        bool needsInput() const;

        /**
         * @return true if a preset dictionary is needed for decompression.
         */
        bool needsDictionary() const;

        /**
         * When called, indicates that decompression should end with the current contents of
         * the input buffer.
         */
        void finish();

        /**
         * @return true if the end of the compressed data output stream has been reached.
         */
        bool finished() const;

        /**
         * Uncompresses bytes into specified buffer. Returns actual number of bytes uncompressed.
         * A return value of 0 indicates that needsInput() or needsDictionary() should be called
         * in order to determine if more input data or a preset dictionary is required. In the
         * latter case, getAdler() can be used to get the Adler-32 value of the dictionary required.
         *
         * @param buffer
         *      The Buffer to write the compressed data to.
         * @param size
         *      The size of the buffer passed in.
         * @param offset
         *      The position in the Buffer to start writing at.
         * @param length
         *      The maximum number of byte of data to write.
         *
         * @throws NullPointerException if buffer is NULL.
         * @throws IllegalStateException if in the end state.
         * @throws IndexOutOfBoundsException if the offset + length > size of the buffer.
         * @throws DataFormatException if the compressed data format is invalid.
         */
        int inflate(unsigned char* buffer, int size, int offset, int length);

        /**
         * Uncompresses bytes into specified buffer. Returns actual number of bytes uncompressed.
         * A return value of 0 indicates that needsInput() or needsDictionary() should be called
         * in order to determine if more input data or a preset dictionary is required. In the
         * latter case, getAdler() can be used to get the Adler-32 value of the dictionary required.
         *
         * @param buffer
         *      The Buffer to write the compressed data to.
         * @param offset
         *      The position in the Buffer to start writing at.
         * @param length
         *      The maximum number of byte of data to write.
         *
         * @throws IllegalStateException if in the end state.
         * @throws IndexOutOfBoundsException if the offset + length > size of the buffer.
         * @throws DataFormatException if the compressed data format is invalid.
         */
        int inflate(std::vector<unsigned char>& buffer, int offset, int length);

        /**
         * Uncompresses bytes into specified buffer. Returns actual number of bytes uncompressed.
         * A return value of 0 indicates that needsInput() or needsDictionary() should be called
         * in order to determine if more input data or a preset dictionary is required. In the
         * latter case, getAdler() can be used to get the Adler-32 value of the dictionary required.
         *
         * @param buffer
         *      The Buffer to write the compressed data to.
         *
         * @throws IllegalStateException if in the end state.
         * @throws DataFormatException if the compressed data format is invalid.
         */
        int inflate(std::vector<unsigned char>& buffer);

        /**
         * @return the ADLER-32 value of the uncompressed data.
         *
         * @throws IllegalStateException if in the end state.
         */
        long long getAdler() const;

        /**
         * @return the total number of compressed bytes input so far.
         *
         * @throws IllegalStateException if in the end state.
         */
        long long getBytesRead() const;

        /**
         * @return the total number of decompressed bytes output so far.
         *
         * @throws IllegalStateException if in the end state.
         */
        long long getBytesWritten() const;

        /**
         * Resets deflater so that a new set of input data can be processed. Keeps current decompression
         * level and strategy settings.
         *
         * @throws IllegalStateException if in the end state.
         */
        void reset();

        /**
         * Closes the decompressor and discards any unprocessed input. This method should be called
         * when the decompressor is no longer being used, but will also be called automatically by the
         * destructor. Once this method is called, the behavior of the Inflater object is undefined.
         */
        void end();

    };

}}}

#endif /* _DECAF_UTI_ZIP_INFLATER_H_ */
