/*
 *  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 java.io;

/**
 * Wraps an existing {@link InputStream} and adds functionality to "push back"
 * bytes that have been read, so that they can be read again. Parsers may find
 * this useful. The number of bytes which may be pushed back can be specified
 * during construction. If the buffer of pushed back bytes is empty, bytes are
 * read from the underlying input stream.
 */
public class PushbackInputStream extends FilterInputStream {
    /**
     * The buffer that contains pushed-back bytes.
     */
    protected byte[] buf;

    /**
     * The current position within {@code buf}. A value equal to
     * {@code buf.length} indicates that no bytes are available. A value of 0
     * indicates that the buffer is full.
     */
    protected int pos;

    /**
     * Constructs a new {@code PushbackInputStream} with the specified input
     * stream as source. The size of the pushback buffer is set to the default
     * value of 1 byte.
     *
     * <p><strong>Warning:</strong> passing a null source creates an invalid
     * {@code PushbackInputStream}. All read operations on such a stream will
     * fail.
     *
     * @param in
     *            the source input stream.
     */
    public PushbackInputStream(InputStream in) {
        super(in);
        buf = (in == null) ? null : new byte[1];
        pos = 1;
    }

    /**
     * Constructs a new {@code PushbackInputStream} with {@code in} as source
     * input stream. The size of the pushback buffer is set to {@code size}.
     *
     * <p><strong>Warning:</strong> passing a null source creates an invalid
     * {@code PushbackInputStream}. All read operations on such a stream will
     * fail.
     *
     * @param in
     *            the source input stream.
     * @param size
     *            the size of the pushback buffer.
     * @throws IllegalArgumentException
     *             if {@code size} is negative.
     */
    public PushbackInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("size <= 0");
        }
        buf = (in == null) ? null : new byte[size];
        pos = size;
    }

    @Override
    public int available() throws IOException {
        if (buf == null) {
            throw new IOException();
        }
        return buf.length - pos + in.available();
    }

    /**
     * Closes this stream. This implementation closes the source stream
     * and releases the pushback buffer.
     *
     * @throws IOException
     *             if an error occurs while closing this stream.
     */
    @Override
    public void close() throws IOException {
        if (in != null) {
            in.close();
            in = null;
            buf = null;
        }
    }

    /**
     * Indicates whether this stream supports the {@code mark(int)} and
     * {@code reset()} methods. {@code PushbackInputStream} does not support
     * them, so it returns {@code false}.
     *
     * @return always {@code false}.
     * @see #mark(int)
     * @see #reset()
     */
    @Override
    public boolean markSupported() {
        return false;
    }

    /**
     * Reads a single byte from this stream and returns it as an integer in the
     * range from 0 to 255. If the pushback buffer does not contain any
     * available bytes then a byte from the source input stream is returned.
     * Blocks until one byte has been read, the end of the source stream is
     * detected or an exception is thrown.
     *
     * @return the byte read or -1 if the end of the source stream has been
     *         reached.
     * @throws IOException
     *             if this stream is closed or an I/O error occurs while reading
     *             from this stream.
     */
    @Override
    public int read() throws IOException {
        if (buf == null) {
            throw new IOException();
        }
        // Is there a pushback byte available?
        if (pos < buf.length) {
            return (buf[pos++] & 0xFF);
        }
        // Assume read() in the InputStream will return low-order byte or -1
        // if end of stream.
        return in.read();
    }

    /**
     * Reads at most {@code length} bytes from this stream and stores them in
     * the byte array {@code buffer} starting at {@code offset}. Bytes are read
     * from the pushback buffer first, then from the source stream if more bytes
     * are required. Blocks until {@code count} bytes have been read, the end of
     * the source stream is detected or an exception is thrown.
     *
     * @param buffer
     *            the array in which to store the bytes read from this stream.
     * @param offset
     *            the initial position in {@code buffer} to store the bytes read
     *            from this stream.
     * @param length
     *            the maximum number of bytes to store in {@code buffer}.
     * @return the number of bytes read or -1 if the end of the source stream
     *         has been reached.
     * @throws IndexOutOfBoundsException
     *             if {@code offset < 0} or {@code length < 0}, or if
     *             {@code offset + length} is greater than the length of
     *             {@code buffer}.
     * @throws IOException
     *             if this stream is closed or another I/O error occurs while
     *             reading from this stream.
     * @throws NullPointerException
     *             if {@code buffer} is {@code null}.
     */
    @Override
    public int read(byte[] buffer, int offset, int length) throws IOException {
        if (buf == null) {
            throw streamClosed();
        }
        // Force buffer null check first!
        if (offset > buffer.length || offset < 0) {
            throw new ArrayIndexOutOfBoundsException("Offset out of bounds: " + offset);
        }
        if (length < 0 || length > buffer.length - offset) {
            throw new ArrayIndexOutOfBoundsException("Length out of bounds: " + length);
        }

        int copiedBytes = 0, copyLength = 0, newOffset = offset;
        // Are there pushback bytes available?
        if (pos < buf.length) {
            copyLength = (buf.length - pos >= length) ? length : buf.length
                    - pos;
            System.arraycopy(buf, pos, buffer, newOffset, copyLength);
            newOffset += copyLength;
            copiedBytes += copyLength;
            // Use up the bytes in the local buffer
            pos += copyLength;
        }
        // Have we copied enough?
        if (copyLength == length) {
            return length;
        }
        int inCopied = in.read(buffer, newOffset, length - copiedBytes);
        if (inCopied > 0) {
            return inCopied + copiedBytes;
        }
        if (copiedBytes == 0) {
            return inCopied;
        }
        return copiedBytes;
    }

    private IOException streamClosed() throws IOException  {
        throw new IOException("PushbackInputStream is closed");
    }

    /**
     * Skips {@code count} bytes in this stream. This implementation skips bytes
     * in the pushback buffer first and then in the source stream if necessary.
     *
     * @param count
     *            the number of bytes to skip.
     * @return the number of bytes actually skipped.
     * @throws IOException
     *             if this stream is closed or another I/O error occurs.
     */
    @Override
    public long skip(long count) throws IOException {
        if (in == null) {
            throw streamClosed();
        }
        if (count <= 0) {
            return 0;
        }
        int numSkipped = 0;
        if (pos < buf.length) {
            numSkipped += (count < buf.length - pos) ? count : buf.length - pos;
            pos += numSkipped;
        }
        if (numSkipped < count) {
            numSkipped += in.skip(count - numSkipped);
        }
        return numSkipped;
    }

    /**
     * Pushes all the bytes in {@code buffer} back to this stream. The bytes are
     * pushed back in such a way that the next byte read from this stream is
     * buffer[0], then buffer[1] and so on.
     * <p>
     * If this stream's internal pushback buffer cannot store the entire
     * contents of {@code buffer}, an {@code IOException} is thrown. Parts of
     * {@code buffer} may have already been copied to the pushback buffer when
     * the exception is thrown.
     *
     * @param buffer
     *            the buffer containing the bytes to push back to this stream.
     * @throws IOException
     *             if the free space in the internal pushback buffer is not
     *             sufficient to store the contents of {@code buffer}.
     */
    public void unread(byte[] buffer) throws IOException {
        unread(buffer, 0, buffer.length);
    }

    /**
     * Pushes a subset of the bytes in {@code buffer} back to this stream. The
     * subset is defined by the start position {@code offset} within
     * {@code buffer} and the number of bytes specified by {@code length}. The
     * bytes are pushed back in such a way that the next byte read from this
     * stream is {@code buffer[offset]}, then {@code buffer[1]} and so on.
     * <p>
     * If this stream's internal pushback buffer cannot store the selected
     * subset of {@code buffer}, an {@code IOException} is thrown. Parts of
     * {@code buffer} may have already been copied to the pushback buffer when
     * the exception is thrown.
     *
     * @param buffer
     *            the buffer containing the bytes to push back to this stream.
     * @param offset
     *            the index of the first byte in {@code buffer} to push back.
     * @param length
     *            the number of bytes to push back.
     * @throws IndexOutOfBoundsException
     *             if {@code offset < 0} or {@code length < 0}, or if
     *             {@code offset + length} is greater than the length of
     *             {@code buffer}.
     * @throws IOException
     *             if the free space in the internal pushback buffer is not
     *             sufficient to store the selected contents of {@code buffer}.
     */
    public void unread(byte[] buffer, int offset, int length) throws IOException {
        if (length > pos) {
            throw new IOException("Pushback buffer full");
        }
        if (offset > buffer.length || offset < 0) {
            throw new ArrayIndexOutOfBoundsException("Offset out of bounds: " + offset);
        }
        if (length < 0 || length > buffer.length - offset) {
            throw new ArrayIndexOutOfBoundsException("Length out of bounds: " + length);
        }
        if (buf == null) {
            throw streamClosed();
        }

        System.arraycopy(buffer, offset, buf, pos - length, length);
        pos = pos - length;
    }

    /**
     * Pushes the specified byte {@code oneByte} back to this stream. Only the
     * least significant byte of the integer {@code oneByte} is pushed back.
     * This is done in such a way that the next byte read from this stream is
     * {@code (byte) oneByte}.
     * <p>
     * If this stream's internal pushback buffer cannot store the byte, an
     * {@code IOException} is thrown.
     *
     * @param oneByte
     *            the byte to push back to this stream.
     * @throws IOException
     *             if this stream is closed or the internal pushback buffer is
     *             full.
     */
    public void unread(int oneByte) throws IOException {
        if (buf == null) {
            throw new IOException();
        }
        if (pos == 0) {
            throw new IOException("Pushback buffer full");
        }
        buf[--pos] = (byte) oneByte;
    }

    /**
     * Marks the current position in this stream. Setting a mark is not
     * supported in this class; this implementation does nothing.
     *
     * @param readlimit
     *            the number of bytes that can be read from this stream before
     *            the mark is invalidated; this parameter is ignored.
     */
    @Override
    public void mark(int readlimit) {
        return;
    }

    /**
     * Resets this stream to the last marked position. Resetting the stream is
     * not supported in this class; this implementation always throws an
     * {@code IOException}.
     *
     * @throws IOException
     *             if this method is called.
     */
    @Override
    public void reset() throws IOException {
        throw new IOException();
    }
}
