/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * This package is based on the work done by Timothy Gerard Endres 
 * (time@ice.com) to whom the Ant project is very grateful for his great code.
 */

package org.apache.tools.tar;

import java.io.*;

/**
 * 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 Timothy Gerard Endres <a href="mailto:time@ice.com">time@ice.com</a>
 * @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">stefano@apache.org</a>
 */
public class TarInputStream extends FilterInputStream {
    
    protected boolean      debug;
    protected boolean      hasHitEOF;
    protected int          entrySize;
    protected int          entryOffset;
    protected byte[]       oneBuf;
    protected byte[]       readBuf;
    protected TarBuffer    buffer;
    protected TarEntry     currEntry;

    public TarInputStream(InputStream is) {
        this(is, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE);
    }

    public TarInputStream(InputStream is, int blockSize) {
        this(is, blockSize, TarBuffer.DEFAULT_RCDSIZE);
    }

    public TarInputStream(InputStream is, int blockSize, int recordSize) {
        super(is);

        this.buffer = new TarBuffer(is, blockSize, recordSize);
        this.readBuf = null;
        this.oneBuf = new byte[1];
        this.debug = false;
        this.hasHitEOF = false;
    }

    /**
     * Sets the debugging flag.
     * 
     * @param debugF True to turn on debugging.
     */
    public void setDebug(boolean debug) {
        this.debug = debug;
        this.buffer.setDebug(debug);
    } 

    /**
     * Closes this stream. Calls the TarBuffer's close() method.
     */
    public void close() throws IOException {
        this.buffer.close();
    } 

    /**
     * Get the record size being used by this stream's TarBuffer.
     * 
     * @return The TarBuffer record size.
     */
    public int getRecordSize() {
        return this.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.
     */
    public int available() throws IOException {
        return this.entrySize - this.entryOffset;
    } 

    /**
     * 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.
     */
    public void skip(int numToSkip) throws IOException {

        // REVIEW
        // This is horribly inefficient, but it ensures that we
        // properly skip over bytes via the TarBuffer...
        // 
        byte[] skipBuf = new byte[8 * 1024];

        for (int num = numToSkip; num > 0; ) {
            int numRead = this.read(skipBuf, 0, 
                                    (num > skipBuf.length ? skipBuf.length 
                                     : num));

            if (numRead == -1) {
                break;
            } 

            num -= numRead;
        } 
    } 

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

    /**
     * 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 do nothing.
     */
    public void reset() {}

    /**
     * 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.
     */
    public TarEntry getNextEntry() throws IOException {
        if (this.hasHitEOF) {
            return null;
        } 

        if (this.currEntry != null) {
            int numToSkip = this.entrySize - this.entryOffset;

            if (this.debug) {
                System.err.println("TarInputStream: SKIP currENTRY '" 
                                   + this.currEntry.getName() + "' SZ " 
                                   + this.entrySize + " OFF " 
                                   + this.entryOffset + "  skipping " 
                                   + numToSkip + " bytes");
            } 

            if (numToSkip > 0) {
                this.skip(numToSkip);
            } 

            this.readBuf = null;
        } 

        byte[] headerBuf = this.buffer.readRecord();

        if (headerBuf == null) {
            if (this.debug) {
                System.err.println("READ NULL RECORD");
            } 
            this.hasHitEOF = true;
        } else if (this.buffer.isEOFRecord(headerBuf)) {
            if (this.debug) {
                System.err.println("READ EOF RECORD");
            } 
            this.hasHitEOF = true;
        } 

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

            if (!(headerBuf[257] == 'u' && headerBuf[258] == 's' 
                    && headerBuf[259] == 't' && headerBuf[260] == 'a' 
                    && headerBuf[261] == 'r')) {
                this.entrySize = 0;
                this.entryOffset = 0;
                this.currEntry = null;

                throw new IOException("bad header in block " 
                                                 + this.buffer.getCurrentBlockNum() 
                                                 + " record " 
                                                 + this.buffer.getCurrentRecordNum() 
                                                 + ", " + 
                                       "header magic is not 'ustar', but '" 
                                                 + headerBuf[257] 
                                                 + headerBuf[258] 
                                                 + headerBuf[259] 
                                                 + headerBuf[260] 
                                                 + headerBuf[261] 
                                                 + "', or (dec) " 
                                                 + ((int) headerBuf[257]) 
                                                 + ", " 
                                                 + ((int) headerBuf[258]) 
                                                 + ", " 
                                                 + ((int) headerBuf[259]) 
                                                 + ", " 
                                                 + ((int) headerBuf[260]) 
                                                 + ", " 
                                                 + ((int) headerBuf[261]));
            } 

            if (this.debug) {
                System.err.println("TarInputStream: SET CURRENTRY '" 
                                   + this.currEntry.getName() 
                                   + "' size = " 
                                   + this.currEntry.getSize());
            } 

            this.entryOffset = 0;

            // REVIEW How do we resolve this discrepancy?!
            this.entrySize = (int) this.currEntry.getSize();
        } 

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

        return this.currEntry;
    } 

    /**
     * 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.
     */
    public int read() throws IOException {
        int num = this.read(this.oneBuf, 0, 1);

        if (num == -1) {
            return num;
        } else {
            return (int) this.oneBuf[0];
        }
    } 

    /**
     * Reads bytes from the current tar archive entry.
     * 
     * This method simply calls read( byte[], int, int ).
     * 
     * @param buf The buffer into which to place bytes read.
     * @return The number of bytes read, or -1 at EOF.
     */
    public int read(byte[] buf) throws IOException {
        return this.read(buf, 0, buf.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 buf The buffer into which to place bytes read.
     * @param offset The offset at which to place bytes read.
     * @param numToRead The number of bytes to read.
     * @return The number of bytes read, or -1 at EOF.
     */
    public int read(byte[] buf, int offset, int numToRead) throws IOException {
        int totalRead = 0;

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

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

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

            System.arraycopy(this.readBuf, 0, buf, offset, sz);

            if (sz >= this.readBuf.length) {
                this.readBuf = null;
            } else {
                int    newLen = this.readBuf.length - sz;
                byte[] newBuf = new byte[newLen];

                System.arraycopy(this.readBuf, sz, newBuf, 0, newLen);

                this.readBuf = newBuf;
            } 

            totalRead += sz;
            numToRead -= sz;
            offset += sz;
        } 

        while (numToRead > 0) {
            byte[] rec = this.buffer.readRecord();

            if (rec == null) {
                // Unexpected EOF!
                throw new IOException("unexpected EOF with " + numToRead 
                                      + " bytes unread");
            } 

            int sz = numToRead;
            int recLen = rec.length;

            if (recLen > sz) {
                System.arraycopy(rec, 0, buf, offset, sz);

                this.readBuf = new byte[recLen - sz];

                System.arraycopy(rec, sz, this.readBuf, 0, recLen - sz);
            } else {
                sz = recLen;

                System.arraycopy(rec, 0, buf, offset, recLen);
            } 

            totalRead += sz;
            numToRead -= sz;
            offset += sz;
        } 

        this.entryOffset += totalRead;

        return totalRead;
    } 

    /**
     * Copies the contents of the current tar archive entry directly into
     * an output stream.
     * 
     * @param out The OutputStream into which to write the entry's data.
     */
    public void copyEntryContents(OutputStream out) throws IOException {
        byte[] buf = new byte[32 * 1024];

        while (true) {
            int numRead = this.read(buf, 0, buf.length);

            if (numRead == -1) {
                break;
            } 

            out.write(buf, 0, numRead);
        } 
    } 
}
