/*
 * BlockInputStream
 *
 * Author: Lasse Collin <lasse.collin@tukaani.org>
 *
 * This file has been put into the public domain.
 * You can do whatever you want with this file.
 */

package org.tukaani.xz;

import java.io.InputStream;
import java.io.DataInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Arrays;
import org.tukaani.xz.common.DecoderUtil;
import org.tukaani.xz.check.Check;

class BlockInputStream extends InputStream {
    private final DataInputStream inData;
    private final CountingInputStream inCounted;
    private InputStream filterChain;
    private final Check check;
    private final boolean verifyCheck;

    private long uncompressedSizeInHeader = -1;
    private long compressedSizeInHeader = -1;
    private long compressedSizeLimit;
    private final int headerSize;
    private long uncompressedSize = 0;
    private boolean endReached = false;

    private final byte[] tempBuf = new byte[1];

    public BlockInputStream(InputStream in,
                            Check check, boolean verifyCheck,
                            int memoryLimit,
                            long unpaddedSizeInIndex,
                            long uncompressedSizeInIndex)
            throws IOException, IndexIndicatorException {
        this.check = check;
        this.verifyCheck = verifyCheck;
        inData = new DataInputStream(in);

        byte[] buf = new byte[DecoderUtil.BLOCK_HEADER_SIZE_MAX];

        // Block Header Size or Index Indicator
        inData.readFully(buf, 0, 1);

        // See if this begins the Index field.
        if (buf[0] == 0x00)
            throw new IndexIndicatorException();

        // Read the rest of the Block Header.
        headerSize = 4 * ((buf[0] & 0xFF) + 1);
        inData.readFully(buf, 1, headerSize - 1);

        // Validate the CRC32.
        if (!DecoderUtil.isCRC32Valid(buf, 0, headerSize - 4, headerSize - 4))
            throw new CorruptedInputException("XZ Block Header is corrupt");

        // Check for reserved bits in Block Flags.
        if ((buf[1] & 0x3C) != 0)
            throw new UnsupportedOptionsException(
                    "Unsupported options in XZ Block Header");

        // Memory for the Filter Flags field
        int filterCount = (buf[1] & 0x03) + 1;
        long[] filterIDs = new long[filterCount];
        byte[][] filterProps = new byte[filterCount][];

        // Use a stream to parse the fields after the Block Flags field.
        // Exclude the CRC32 field at the end.
        ByteArrayInputStream bufStream = new ByteArrayInputStream(
                buf, 2, headerSize - 6);

        try {
            // Set the maximum valid compressed size. This is overriden
            // by the value from the Compressed Size field if it is present.
            compressedSizeLimit = (DecoderUtil.VLI_MAX & ~3)
                                  - headerSize - check.getSize();

            // Decode and validate Compressed Size if the relevant flag
            // is set in Block Flags.
            if ((buf[1] & 0x40) != 0x00) {
                compressedSizeInHeader = DecoderUtil.decodeVLI(bufStream);

                if (compressedSizeInHeader == 0
                        || compressedSizeInHeader > compressedSizeLimit)
                    throw new CorruptedInputException();

                compressedSizeLimit = compressedSizeInHeader;
            }

            // Decode Uncompressed Size if the relevant flag is set
            // in Block Flags.
            if ((buf[1] & 0x80) != 0x00)
                uncompressedSizeInHeader = DecoderUtil.decodeVLI(bufStream);

            // Decode Filter Flags.
            for (int i = 0; i < filterCount; ++i) {
                filterIDs[i] = DecoderUtil.decodeVLI(bufStream);

                long filterPropsSize = DecoderUtil.decodeVLI(bufStream);
                if (filterPropsSize > bufStream.available())
                    throw new CorruptedInputException();

                filterProps[i] = new byte[(int)filterPropsSize];
                bufStream.read(filterProps[i]);
            }

        } catch (IOException e) {
            throw new CorruptedInputException("XZ Block Header is corrupt");
        }

        // Check that the remaining bytes are zero.
        for (int i = bufStream.available(); i > 0; --i)
            if (bufStream.read() != 0x00)
                throw new UnsupportedOptionsException(
                        "Unsupported options in XZ Block Header");

        // Validate the Blcok Header against the Index when doing
        // random access reading.
        if (unpaddedSizeInIndex != -1) {
            // Compressed Data must be at least one byte, so if Block Header
            // and Check alone take as much or more space than the size
            // stored in the Index, the file is corrupt.
            int headerAndCheckSize = headerSize + check.getSize();
            if (headerAndCheckSize >= unpaddedSizeInIndex)
                throw new CorruptedInputException(
                        "XZ Index does not match a Block Header");

            // The compressed size calculated from Unpadded Size must
            // match the value stored in the Compressed Size field in
            // the Block Header.
            long compressedSizeFromIndex
                    = unpaddedSizeInIndex - headerAndCheckSize;
            if (compressedSizeFromIndex > compressedSizeLimit
                    || (compressedSizeInHeader != -1
                        && compressedSizeInHeader != compressedSizeFromIndex))
                throw new CorruptedInputException(
                        "XZ Index does not match a Block Header");

            // The uncompressed size stored in the Index must match
            // the value stored in the Uncompressed Size field in
            // the Block Header.
            if (uncompressedSizeInHeader != -1
                    && uncompressedSizeInHeader != uncompressedSizeInIndex)
                throw new CorruptedInputException(
                        "XZ Index does not match a Block Header");

            // For further validation, pretend that the values from the Index
            // were stored in the Block Header.
            compressedSizeLimit = compressedSizeFromIndex;
            compressedSizeInHeader = compressedSizeFromIndex;
            uncompressedSizeInHeader = uncompressedSizeInIndex;
        }

        // Check if the Filter IDs are supported, decode
        // the Filter Properties, and check that they are
        // supported by this decoder implementation.
        FilterDecoder[] filters = new FilterDecoder[filterIDs.length];

        for (int i = 0; i < filters.length; ++i) {
            if (filterIDs[i] == LZMA2Coder.FILTER_ID)
                filters[i] = new LZMA2Decoder(filterProps[i]);

            else if (filterIDs[i] == DeltaCoder.FILTER_ID)
                filters[i] = new DeltaDecoder(filterProps[i]);

            else if (BCJDecoder.isBCJFilterID(filterIDs[i]))
                filters[i] = new BCJDecoder(filterIDs[i], filterProps[i]);

            else
                throw new UnsupportedOptionsException(
                        "Unknown Filter ID " + filterIDs[i]);
        }

        RawCoder.validate(filters);

        // Check the memory usage limit.
        if (memoryLimit >= 0) {
            int memoryNeeded = 0;
            for (int i = 0; i < filters.length; ++i)
                memoryNeeded += filters[i].getMemoryUsage();

            if (memoryNeeded > memoryLimit)
                throw new MemoryLimitException(memoryNeeded, memoryLimit);
        }

        // Use an input size counter to calculate
        // the size of the Compressed Data field.
        inCounted = new CountingInputStream(in);

        // Initialize the filter chain.
        filterChain = inCounted;
        for (int i = filters.length - 1; i >= 0; --i)
            filterChain = filters[i].getInputStream(filterChain);
    }

    public int read() throws IOException {
        return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
    }

    public int read(byte[] buf, int off, int len) throws IOException {
        if (endReached)
            return -1;

        int ret = filterChain.read(buf, off, len);

        if (ret > 0) {
            if (verifyCheck)
                check.update(buf, off, ret);

            uncompressedSize += ret;

            // Catch invalid values.
            long compressedSize = inCounted.getSize();
            if (compressedSize < 0
                    || compressedSize > compressedSizeLimit
                    || uncompressedSize < 0
                    || (uncompressedSizeInHeader != -1
                        && uncompressedSize > uncompressedSizeInHeader))
                throw new CorruptedInputException();

            // Check the Block integrity as soon as possible:
            //   - The filter chain shouldn't return less than requested
            //     unless it hit the end of the input.
            //   - If the uncompressed size is known, we know when there
            //     shouldn't be more data coming. We still need to read
            //     one byte to let the filter chain catch errors and to
            //     let it read end of payload marker(s).
            if (ret < len || uncompressedSize == uncompressedSizeInHeader) {
                if (filterChain.read() != -1)
                    throw new CorruptedInputException();

                validate();
                endReached = true;
            }
        } else if (ret == -1) {
            validate();
            endReached = true;
        }

        return ret;
    }

    private void validate() throws IOException {
        long compressedSize = inCounted.getSize();

        // Validate Compressed Size and Uncompressed Size if they were
        // present in Block Header.
        if ((compressedSizeInHeader != -1
                    && compressedSizeInHeader != compressedSize)
                || (uncompressedSizeInHeader != -1
                    && uncompressedSizeInHeader != uncompressedSize))
            throw new CorruptedInputException();

        // Block Padding bytes must be zeros.
        while ((compressedSize++ & 3) != 0)
            if (inData.readUnsignedByte() != 0x00)
                throw new CorruptedInputException();

        // Validate the integrity check if verifyCheck is true.
        byte[] storedCheck = new byte[check.getSize()];
        inData.readFully(storedCheck);
        if (verifyCheck && !Arrays.equals(check.finish(), storedCheck))
            throw new CorruptedInputException("Integrity check ("
                    + check.getName() + ") does not match");
    }

    public int available() throws IOException {
        return filterChain.available();
    }

    public long getUnpaddedSize() {
        return headerSize + inCounted.getSize() + check.getSize();
    }

    public long getUncompressedSize() {
        return uncompressedSize;
    }
}
