/*
 * 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.commons.vfs.provider.tar;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * The TarInputStream reads a UNIX tar archive as an InputStream. methods are
 * provided to position at each successive entry in the archive, and the read
 * each entry as a normal input stream using read().
 *
 * @author <a href="mailto:time@ice.com">Timothy Gerard Endres</a>
 * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
 * @author <a href="mailto:peter@apache.org">Peter Donald</a>
 * @version $Revision$ $Date$
 * @see TarInputStream
 * @see TarEntry
 */
class TarInputStream
        extends FilterInputStream
{
    private TarBuffer buffer;
    private TarEntry currEntry;
    private boolean debug;
    private int entryOffset;
    private long entrySize;
    private boolean hasHitEOF;
    private byte[] oneBuf;
    private byte[] readBuf;

    /**
     * Construct a TarInputStream using specified input
     * stream and default block and record sizes.
     *
     * @param input stream to create TarInputStream from
     * @see TarBuffer#DEFAULT_BLOCKSIZE
     * @see TarBuffer#DEFAULT_RECORDSIZE
     */
    TarInputStream(final InputStream input)
    {
        this(input, TarBuffer.DEFAULT_BLOCKSIZE, TarBuffer.DEFAULT_RECORDSIZE);
    }

    /**
     * Construct a TarInputStream using specified input
     * stream, block size and default record sizes.
     *
     * @param input     stream to create TarInputStream from
     * @param blockSize the block size to use
     * @see TarBuffer#DEFAULT_RECORDSIZE
     */
    TarInputStream(final InputStream input,
                   final int blockSize)
    {
        this(input, blockSize, TarBuffer.DEFAULT_RECORDSIZE);
    }

    /**
     * Construct a TarInputStream using specified input
     * stream, block size and record sizes.
     *
     * @param input      stream to create TarInputStream from
     * @param blockSize  the block size to use
     * @param recordSize the record size to use
     */
    TarInputStream(final InputStream input,
                   final int blockSize,
                   final int recordSize)
    {
        super(input);

        buffer = new TarBuffer(input, blockSize, recordSize);
        oneBuf = new byte[1];
    }

    /**
     * Sets the debugging flag.
     *
     * @param debug The new Debug value
     */
    public void setDebug(final boolean debug)
    {
        this.debug = debug;
        buffer.setDebug(debug);
    }

    /**
     * Get the next entry in this tar archive. This will skip over any remaining
     * data in the current entry, if there is one, and place the input stream at
     * the header of the next entry, and read the header and instantiate a new
     * TarEntry from the header bytes and return that entry. If there are no
     * more entries in the archive, null will be returned to indicate that the
     * end of the archive has been reached.
     *
     * @return The next TarEntry in the archive, or null.
     * @throws IOException Description of Exception
     */
    public TarEntry getNextEntry()
            throws IOException
    {
        if (hasHitEOF)
        {
            return null;
        }

        if (currEntry != null)
        {
            final long numToSkip = entrySize - entryOffset;

            if (debug)
            {
                final String message = "TarInputStream: SKIP currENTRY '" +
                        currEntry.getName() + "' SZ " + entrySize +
                        " OFF " + entryOffset + "  skipping " + numToSkip + " bytes";
                debug(message);
            }

            if (numToSkip > 0)
            {
                // Use our internal skip to move to the end of the current entry
                longSkip(numToSkip);
            }

            readBuf = null;
        }

        final byte[] headerBuf = buffer.readRecord();
        if (headerBuf == null)
        {
            if (debug)
            {
                debug("READ NULL RECORD");
            }
            hasHitEOF = true;
        }
        else if (buffer.isEOFRecord(headerBuf))
        {
            if (debug)
            {
                debug("READ EOF RECORD");
            }
            hasHitEOF = true;
        }

        if (hasHitEOF)
        {
            currEntry = null;
        }
        else
        {
            currEntry = new TarEntry(headerBuf);

            if (!(headerBuf[257] == 'u' && headerBuf[258] == 's' &&
                    headerBuf[259] == 't' && headerBuf[260] == 'a' &&
                    headerBuf[261] == 'r'))
            {
                //Must be v7Format
            }

            if (debug)
            {
                final String message = "TarInputStream: SET CURRENTRY '" +
                        currEntry.getName() + "' size = " + currEntry.getSize();
                debug(message);
            }

            entryOffset = 0;

            entrySize = currEntry.getSize();
        }

        if (null != currEntry && currEntry.isGNULongNameEntry())
        {
            // read in the name
            final StringBuffer longName = new StringBuffer();
            final byte[] buffer = new byte[256];
            int length = 0;
            while ((length = read(buffer)) >= 0)
            {
                final String str = new String(buffer, 0, length);
                longName.append(str);
            }
            getNextEntry();

            // remove trailing null terminator
            if (longName.length() > 0
                    && longName.charAt(longName.length() - 1) == 0)
            {
                longName.deleteCharAt(longName.length() - 1);
            }

            currEntry.setName(longName.toString());
        }

        return currEntry;
    }

    /**
     * Get the record size being used by this stream's TarBuffer.
     *
     * @return The TarBuffer record size.
     */
    public int getRecordSize()
    {
        return buffer.getRecordSize();
    }

    /**
     * Get the available data that can be read from the current entry in the
     * archive. This does not indicate how much data is left in the entire
     * archive, only in the current entry. This value is determined from the
     * entry's size header field and the amount of data already read from the
     * current entry.
     *
     * @return The number of available bytes for the current entry.
     * @throws IOException when an IO error causes operation to fail
     */
    public int available()
            throws IOException
    {
      long remaining = entrySize - entryOffset;
      
      if(remaining > Integer.MAX_VALUE) {
        return Integer.MAX_VALUE;
      }
      
      return (int) remaining;
    }

    /**
     * Closes this stream. Calls the TarBuffer's close() method.
     *
     * @throws IOException when an IO error causes operation to fail
     */
    public void close()
            throws IOException
    {
        buffer.close();
    }

    /**
     * Copies the contents of the current tar archive entry directly into an
     * output stream.
     *
     * @param output The OutputStream into which to write the entry's data.
     * @throws IOException when an IO error causes operation to fail
     */
    public void copyEntryContents(final OutputStream output)
            throws IOException
    {
        final byte[] buffer = new byte[32 * 1024];
        while (true)
        {
            final int numRead = read(buffer, 0, buffer.length);
            if (numRead == -1)
            {
                break;
            }

            output.write(buffer, 0, numRead);
        }
    }

    /**
     * Since we do not support marking just yet, we do nothing.
     *
     * @param markLimit The limit to mark.
     */
    public void mark(int markLimit)
    {
    }

    /**
     * Since we do not support marking just yet, we return false.
     *
     * @return False.
     */
    public boolean markSupported()
    {
        return false;
    }

    /**
     * Reads a byte from the current tar archive entry. This method simply calls
     * read( byte[], int, int ).
     *
     * @return The byte read, or -1 at EOF.
     * @throws IOException when an IO error causes operation to fail
     */
    public int read()
            throws IOException
    {
        final int num = read(oneBuf, 0, 1);
        if (num == -1)
        {
            return num;
        }
        else
        {
            return oneBuf[0];
        }
    }

    /**
     * Reads bytes from the current tar archive entry. This method simply calls
     * read( byte[], int, int ).
     *
     * @param buffer The buffer into which to place bytes read.
     * @return The number of bytes read, or -1 at EOF.
     * @throws IOException when an IO error causes operation to fail
     */
    public int read(final byte[] buffer)
            throws IOException
    {
        return read(buffer, 0, buffer.length);
    }

    /**
     * Reads bytes from the current tar archive entry. This method is aware of
     * the boundaries of the current entry in the archive and will deal with
     * them as if they were this stream's start and EOF.
     *
     * @param buffer The buffer into which to place bytes read.
     * @param offset The offset at which to place bytes read.
     * @param count  The number of bytes to read.
     * @return The number of bytes read, or -1 at EOF.
     * @throws IOException when an IO error causes operation to fail
     */
    public int read(final byte[] buffer,
                    final int offset,
                    final int count)
            throws IOException
    {
        int position = offset;
        int numToRead = count;
        int totalRead = 0;

        if (entryOffset >= entrySize)
        {
            return -1;
        }

        if ((numToRead + entryOffset) > entrySize)
        {
            numToRead = (int)(entrySize - entryOffset);
        }

        if (null != readBuf)
        {
            final int size =
                    (numToRead > readBuf.length) ? readBuf.length : numToRead;

            System.arraycopy(readBuf, 0, buffer, position, size);

            if (size >= readBuf.length)
            {
                readBuf = null;
            }
            else
            {
                final int newLength = readBuf.length - size;
                final byte[] newBuffer = new byte[newLength];

                System.arraycopy(readBuf, size, newBuffer, 0, newLength);

                readBuf = newBuffer;
            }

            totalRead += size;
            numToRead -= size;
            position += size;
        }

        while (numToRead > 0)
        {
            final byte[] rec = this.buffer.readRecord();
            if (null == rec)
            {
                // Unexpected EOF!
                final String message =
                        "unexpected EOF with " + numToRead + " bytes unread";
                throw new IOException(message);
            }

            int size = numToRead;
            final int recordLength = rec.length;

            if (recordLength > size)
            {
                System.arraycopy(rec, 0, buffer, position, size);

                readBuf = new byte[recordLength - size];

                System.arraycopy(rec, size, readBuf, 0, recordLength - size);
            }
            else
            {
                size = recordLength;

                System.arraycopy(rec, 0, buffer, position, recordLength);
            }

            totalRead += size;
            numToRead -= size;
            position += size;
        }

        entryOffset += totalRead;

        return totalRead;
    }

    /**
     * Since we do not support marking just yet, we do nothing.
     */
    public void reset()
    {
    }

    public void longSkip(final long numToSkip) throws IOException {
      for(long skipped = 0; skipped < numToSkip;) {
        if(numToSkip - skipped > Integer.MAX_VALUE) {
          skip(Integer.MAX_VALUE);
          skipped += Integer.MAX_VALUE;
        } else {
          skip((int)(numToSkip - skipped));
          skipped += numToSkip - skipped;
        }
      }
    }
    
    /**
     * Skip bytes in the input buffer. This skips bytes in the current entry's
     * data, not the entire archive, and will stop at the end of the current
     * entry's data if the number to skip extends beyond that point.
     *
     * @param numToSkip The number of bytes to skip.
     * @throws IOException when an IO error causes operation to fail
     */
    public void skip(final int numToSkip)
            throws IOException
    {
        // REVIEW
        // This is horribly inefficient, but it ensures that we
        // properly skip over bytes via the TarBuffer...
        //
        final byte[] skipBuf = new byte[8 * 1024];
        int num = numToSkip;
        while (num > 0)
        {
            final int count = (num > skipBuf.length) ? skipBuf.length : num;
            final int numRead = read(skipBuf, 0, count);
            if (numRead == -1)
            {
                break;
            }

            num -= numRead;
        }
    }

    /**
     * Utility method to do debugging.
     * Capable of being overidden in sub-classes.
     *
     * @param message the message to use in debugging
     */
    protected void debug(final String message)
    {
        if (debug)
        {
            System.err.println(message);
        }
    }
}
