/*
 *  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.mina.filter.compression;

import java.io.IOException;

import org.apache.mina.core.buffer.IoBuffer;

import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZStream;

/**
 * A helper class for interfacing with the JZlib library. This class acts both
 * as a compressor and decompressor, but only as one at a time.  The only
 * flush method supported is <tt>Z_SYNC_FLUSH</tt> also known as <tt>Z_PARTIAL_FLUSH</tt>
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
class Zlib {
    /** Try o get the best possible compression */
    public static final int COMPRESSION_MAX = JZlib.Z_BEST_COMPRESSION;

    /** Favor speed over compression ratio */
    public static final int COMPRESSION_MIN = JZlib.Z_BEST_SPEED;

    /** No compression */
    public static final int COMPRESSION_NONE = JZlib.Z_NO_COMPRESSION;

    /** Default compression */
    public static final int COMPRESSION_DEFAULT = JZlib.Z_DEFAULT_COMPRESSION;

    /** Compression mode */
    public static final int MODE_DEFLATER = 1;

    /** Uncompress mode */
    public static final int MODE_INFLATER = 2;

    /** The requested compression level */
    private int compressionLevel;

    /** The inner stream used to inflate or deflate the data */
    private ZStream zStream = null;

    /** The selected operation mode : INFLATE or DEFLATE */
    private int mode = -1;

    /**
     * Creates an instance of the ZLib class.
     * 
     * @param compressionLevel the level of compression that should be used. One of
     * <tt>COMPRESSION_MAX</tt>, <tt>COMPRESSION_MIN</tt>,
     * <tt>COMPRESSION_NONE</tt> or <tt>COMPRESSION_DEFAULT</tt>
     * @param mode the mode in which the instance will operate. Can be either
     * of <tt>MODE_DEFLATER</tt> or <tt>MODE_INFLATER</tt>
     * @throws IllegalArgumentException if the mode is incorrect
     */
    public Zlib(int compressionLevel, int mode) {
        switch (compressionLevel) {
        case COMPRESSION_MAX:
        case COMPRESSION_MIN:
        case COMPRESSION_NONE:
        case COMPRESSION_DEFAULT:
            this.compressionLevel = compressionLevel;
            break;
        default:
            throw new IllegalArgumentException("invalid compression level specified");
        }

        // create a new instance of ZStream. This will be done only once.
        zStream = new ZStream();

        switch (mode) {
        case MODE_DEFLATER:
            zStream.deflateInit(this.compressionLevel);
            break;
        case MODE_INFLATER:
            zStream.inflateInit();
            break;
        default:
            throw new IllegalArgumentException("invalid mode specified");
        }
        this.mode = mode;
    }

    /**
     * Uncompress the given buffer, returning it in a new buffer.
     * 
     * @param inBuffer the {@link IoBuffer} to be decompressed. The contents
     * of the buffer are transferred into a local byte array and the buffer is
     * flipped and returned intact.
     * @return the decompressed data
     * @throws IOException if the decompression of the data failed for some reason.
     * @throws IllegalArgumentException if the mode is not <code>MODE_DEFLATER</code>
     */
    public IoBuffer inflate(IoBuffer inBuffer) throws IOException {
        if (mode == MODE_DEFLATER) {
            throw new IllegalStateException("not initialized as INFLATER");
        }

        byte[] inBytes = new byte[inBuffer.remaining()];
        inBuffer.get(inBytes).flip();

        // We could probably do this better, if we're willing to return multiple buffers
        // (e.g. with a callback function)
        byte[] outBytes = new byte[inBytes.length * 2];
        IoBuffer outBuffer = IoBuffer.allocate(outBytes.length);
        outBuffer.setAutoExpand(true);

        synchronized (zStream) {
            zStream.next_in = inBytes;
            zStream.next_in_index = 0;
            zStream.avail_in = inBytes.length;
            zStream.next_out = outBytes;
            zStream.next_out_index = 0;
            zStream.avail_out = outBytes.length;
            int retval = 0;

            do {
                retval = zStream.inflate(JZlib.Z_SYNC_FLUSH);
                switch (retval) {
                case JZlib.Z_OK:
                    // completed decompression, lets copy data and get out
                case JZlib.Z_BUF_ERROR:
                    // need more space for output. store current output and get more
                    outBuffer.put(outBytes, 0, zStream.next_out_index);
                    zStream.next_out_index = 0;
                    zStream.avail_out = outBytes.length;
                    break;
                default:
                    // unknown error
                    outBuffer = null;
                    if (zStream.msg == null) {
                        throw new IOException("Unknown error. Error code : " + retval);
                    } else {
                        throw new IOException("Unknown error. Error code : " + retval + " and message : " + zStream.msg);
                    }
                }
            } while (zStream.avail_in > 0);
            
            cleanUp();
        }

        return outBuffer.flip();
    }

    /**
     * Compress the input. The result will be put in a new buffer.
     *  
     * @param inBuffer the buffer to be compressed. The contents are transferred
     * into a local byte array and the buffer is flipped and returned intact.
     * @return the buffer with the compressed data
     * @throws IOException if the compression of teh buffer failed for some reason
     * @throws IllegalStateException if the mode is not <code>MODE_DEFLATER</code>
     */
    public IoBuffer deflate(IoBuffer inBuffer) throws IOException {
        if (mode == MODE_INFLATER) {
            throw new IllegalStateException("not initialized as DEFLATER");
        }

        byte[] inBytes = new byte[inBuffer.remaining()];
        inBuffer.get(inBytes);

        // according to spec, destination buffer should be 0.1% larger
        // than source length plus 12 bytes. We add a single byte to safeguard
        // against rounds that round down to the smaller value
        int outLen = (int) Math.round(inBytes.length * 1.001) + 1 + 12;
        byte[] outBytes = new byte[outLen];

        synchronized (zStream) {
            zStream.next_in = inBytes;
            zStream.next_in_index = 0;
            zStream.avail_in = inBytes.length;
            zStream.next_out = outBytes;
            zStream.next_out_index = 0;
            zStream.avail_out = outBytes.length;

            int retval = zStream.deflate(JZlib.Z_SYNC_FLUSH);
            if (retval != JZlib.Z_OK) {
                outBytes = null;
                inBytes = null;
                throw new IOException("Compression failed with return value : " + retval);
            }

            IoBuffer outBuf = IoBuffer.wrap(outBytes, 0, zStream.next_out_index);

            cleanUp();
            
            return outBuf;
        }
    }

    /**
     * Cleans up the resources used by the compression library.
     */
    public void cleanUp() {
        if (zStream != null) {
            zStream.free();
        }
    }
}
