/*
 * 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.catalina.connector;

import java.io.IOException;
import java.io.Reader;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.servlet.ReadListener;

import org.apache.catalina.security.SecurityUtil;
import org.apache.coyote.ActionCode;
import org.apache.coyote.ContainerThreadMarker;
import org.apache.coyote.Request;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.B2CConverter;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.collections.SynchronizedStack;
import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.res.StringManager;

/**
 * The buffer used by Tomcat request. This is a derivative of the Tomcat 3.3
 * OutputBuffer, adapted to handle input instead of output. This allows
 * complete recycling of the facade objects (the ServletInputStream and the
 * BufferedReader).
 *
 * @author Remy Maucherat
 */
public class InputBuffer extends Reader
    implements ByteChunk.ByteInputChannel, ApplicationBufferHandler {

    /**
     * The string manager for this package.
     */
    protected static final StringManager sm = StringManager.getManager(InputBuffer.class);

    private static final Log log = LogFactory.getLog(InputBuffer.class);

    public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;

    // The buffer can be used for byte[] and char[] reading
    // ( this is needed to support ServletInputStream and BufferedReader )
    public final int INITIAL_STATE = 0;
    public final int CHAR_STATE = 1;
    public final int BYTE_STATE = 2;


    /**
     * Encoder cache.
     */
    private static final Map<Charset, SynchronizedStack<B2CConverter>> encoders = new ConcurrentHashMap<>();

    // ----------------------------------------------------- Instance Variables

    /**
     * The byte buffer.
     */
    private ByteBuffer bb;


    /**
     * The char buffer.
     */
    private CharBuffer cb;


    /**
     * State of the output buffer.
     */
    private int state = 0;


    /**
     * Flag which indicates if the input buffer is closed.
     */
    private boolean closed = false;


    /**
     * Current byte to char converter.
     */
    protected B2CConverter conv;


    /**
     * Associated Coyote request.
     */
    private Request coyoteRequest;


    /**
     * Buffer position.
     */
    private int markPos = -1;


    /**
     * Char buffer limit.
     */
    private int readLimit;


    /**
     * Buffer size.
     */
    private final int size;


    // ----------------------------------------------------------- Constructors


    /**
     * Default constructor. Allocate the buffer with the default buffer size.
     */
    public InputBuffer() {

        this(DEFAULT_BUFFER_SIZE);

    }


    /**
     * Alternate constructor which allows specifying the initial buffer size.
     *
     * @param size Buffer size to use
     */
    public InputBuffer(int size) {

        this.size = size;
        bb = ByteBuffer.allocate(size);
        clear(bb);
        cb = CharBuffer.allocate(size);
        clear(cb);
        readLimit = size;

    }


    // ------------------------------------------------------------- Properties


    /**
     * Associated Coyote request.
     *
     * @param coyoteRequest Associated Coyote request
     */
    public void setRequest(Request coyoteRequest) {
        this.coyoteRequest = coyoteRequest;
    }


    // --------------------------------------------------------- Public Methods

    /**
     * Recycle the output buffer.
     */
    public void recycle() {

        state = INITIAL_STATE;

        // If usage of mark made the buffer too big, reallocate it
        if (cb.capacity() > size) {
            cb = CharBuffer.allocate(size);
            clear(cb);
        } else {
            clear(cb);
        }
        readLimit = size;
        markPos = -1;
        clear(bb);
        closed = false;

        if (conv != null) {
            conv.recycle();
            encoders.get(conv.getCharset()).push(conv);
            conv = null;
        }
    }


    /**
     * Close the input buffer.
     *
     * @throws IOException An underlying IOException occurred
     */
    @Override
    public void close() throws IOException {
        closed = true;
    }


    public int available() {
        int available = availableInThisBuffer();
        if (available == 0) {
            coyoteRequest.action(ActionCode.AVAILABLE,
                    Boolean.valueOf(coyoteRequest.getReadListener() != null));
            available = (coyoteRequest.getAvailable() > 0) ? 1 : 0;
        }
        return available;
    }


    private int availableInThisBuffer() {
        int available = 0;
        if (state == BYTE_STATE) {
            available = bb.remaining();
        } else if (state == CHAR_STATE) {
            available = cb.remaining();
        }
        return available;
    }


    public void setReadListener(ReadListener listener) {
        coyoteRequest.setReadListener(listener);

        // The container is responsible for the first call to
        // listener.onDataAvailable(). If isReady() returns true, the container
        // needs to call listener.onDataAvailable() from a new thread. If
        // isReady() returns false, the socket will be registered for read and
        // the container will call listener.onDataAvailable() once data arrives.
        // Must call isFinished() first as a call to isReady() if the request
        // has been finished will register the socket for read interest and that
        // is not required.
        if (!coyoteRequest.isFinished() && isReady()) {
            coyoteRequest.action(ActionCode.DISPATCH_READ, null);
            if (!ContainerThreadMarker.isContainerThread()) {
                // Not on a container thread so need to execute the dispatch
                coyoteRequest.action(ActionCode.DISPATCH_EXECUTE, null);
            }
        }
    }


    public boolean isFinished() {
        int available = 0;
        if (state == BYTE_STATE) {
            available = bb.remaining();
        } else if (state == CHAR_STATE) {
            available = cb.remaining();
        }
        if (available > 0) {
            return false;
        } else {
            return coyoteRequest.isFinished();
        }
    }


    public boolean isReady() {
        if (coyoteRequest.getReadListener() == null) {
            if (log.isDebugEnabled()) {
                log.debug(sm.getString("inputBuffer.requiresNonBlocking"));
            }
            return false;
        }
        if (isFinished()) {
            // If this is a non-container thread, need to trigger a read
            // which will eventually lead to a call to onAllDataRead() via a
            // container thread.
            if (!ContainerThreadMarker.isContainerThread()) {
                coyoteRequest.action(ActionCode.DISPATCH_READ, null);
                coyoteRequest.action(ActionCode.DISPATCH_EXECUTE, null);
            }
            return false;
        }
        // Checking for available data at the network level and registering for
        // read can be done sequentially for HTTP/1.x and AJP as there is only
        // ever a single thread processing the socket at any one time. However,
        // for HTTP/2 there is one thread processing the connection and separate
        // threads for each stream. For HTTP/2 the two operations have to be
        // performed atomically else it is possible for the connection thread to
        // read more data in to the buffer after the stream thread checks for
        // available network data but before it registers for read.
        if (availableInThisBuffer() > 0) {
            return true;
        }

        AtomicBoolean result = new AtomicBoolean();
        coyoteRequest.action(ActionCode.NB_READ_INTEREST, result);
        return result.get();
    }


    boolean isBlocking() {
        return coyoteRequest.getReadListener() == null;
    }


    // ------------------------------------------------- Bytes Handling Methods

    /**
     * Reads new bytes in the byte chunk.
     *
     * @throws IOException An underlying IOException occurred
     */
    @Override
    public int realReadBytes() throws IOException {
        if (closed) {
            return -1;
        }
        if (coyoteRequest == null) {
            return -1;
        }

        if (state == INITIAL_STATE) {
            state = BYTE_STATE;
        }

        try {
            return coyoteRequest.doRead(this);
        } catch (IOException ioe) {
            // An IOException on a read is almost always due to
            // the remote client aborting the request.
            throw new ClientAbortException(ioe);
        }
    }


    public int readByte() throws IOException {
        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }

        if (checkByteBufferEof()) {
            return -1;
        }
        return bb.get() & 0xFF;
    }


    public int read(byte[] b, int off, int len) throws IOException {
        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }

        if (checkByteBufferEof()) {
            return -1;
        }
        int n = Math.min(len, bb.remaining());
        bb.get(b, off, n);
        return n;
    }


    /**
     * Transfers bytes from the buffer to the specified ByteBuffer. After the
     * operation the position of the ByteBuffer will be returned to the one
     * before the operation, the limit will be the position incremented by
     * the number of the transferred bytes.
     *
     * @param to the ByteBuffer into which bytes are to be written.
     * @return an integer specifying the actual number of bytes read, or -1 if
     *         the end of the stream is reached
     * @throws IOException if an input or output exception has occurred
     */
    public int read(ByteBuffer to) throws IOException {
        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }

        if (checkByteBufferEof()) {
            return -1;
        }
        int n = Math.min(to.remaining(), bb.remaining());
        int orgLimit = bb.limit();
        bb.limit(bb.position() + n);
        to.put(bb);
        bb.limit(orgLimit);
        to.limit(to.position()).position(to.position() - n);
        return n;
    }


    // ------------------------------------------------- Chars Handling Methods

    public int realReadChars() throws IOException {
        checkConverter();

        boolean eof = false;

        if (bb.remaining() <= 0) {
            int nRead = realReadBytes();
            if (nRead < 0) {
                eof = true;
            }
        }

        if (markPos == -1) {
            clear(cb);
        } else {
            // Make sure there's enough space in the worst case
            makeSpace(bb.remaining());
            if ((cb.capacity() - cb.limit()) == 0 && bb.remaining() != 0) {
                // We went over the limit
                clear(cb);
                markPos = -1;
            }
        }

        state = CHAR_STATE;
        conv.convert(bb, cb, this, eof);

        if (cb.remaining() == 0 && eof) {
            return -1;
        } else {
            return cb.remaining();
        }
    }


    @Override
    public int read() throws IOException {

        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }

        if (checkCharBufferEof()) {
            return -1;
        }
        return cb.get();
    }


    @Override
    public int read(char[] cbuf) throws IOException {

        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }

        return read(cbuf, 0, cbuf.length);
    }


    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {

        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }

        if (checkCharBufferEof()) {
            return -1;
        }
        int n = Math.min(len, cb.remaining());
        cb.get(cbuf, off, n);
        return n;
    }


    @Override
    public long skip(long n) throws IOException {
        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }

        if (n < 0) {
            throw new IllegalArgumentException();
        }

        long nRead = 0;
        while (nRead < n) {
            if (cb.remaining() >= n) {
                cb.position(cb.position() + (int) n);
                nRead = n;
            } else {
                nRead += cb.remaining();
                cb.position(cb.limit());
                int nb = realReadChars();
                if (nb < 0) {
                    break;
                }
            }
        }
        return nRead;
    }


    @Override
    public boolean ready() throws IOException {
        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }
        if (state == INITIAL_STATE) {
            state = CHAR_STATE;
        }
        return (available() > 0);
    }


    @Override
    public boolean markSupported() {
        return true;
    }


    @Override
    public void mark(int readAheadLimit) throws IOException {

        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }

        if (cb.remaining() <= 0) {
            clear(cb);
        } else {
            if ((cb.capacity() > (2 * size)) && (cb.remaining()) < (cb.position())) {
                cb.compact();
                cb.flip();
            }
        }
        readLimit = cb.position() + readAheadLimit + size;
        markPos = cb.position();
    }


    @Override
    public void reset() throws IOException {

        if (closed) {
            throw new IOException(sm.getString("inputBuffer.streamClosed"));
        }

        if (state == CHAR_STATE) {
            if (markPos < 0) {
                clear(cb);
                markPos = -1;
                throw new IOException();
            } else {
                cb.position(markPos);
            }
        } else {
            clear(bb);
        }
    }


    public void checkConverter() throws IOException {
        if (conv != null) {
            return;
        }

        Charset charset = null;
        if (coyoteRequest != null) {
            charset = coyoteRequest.getCharset();
        }

        if (charset == null) {
            charset = org.apache.coyote.Constants.DEFAULT_BODY_CHARSET;
        }

        SynchronizedStack<B2CConverter> stack = encoders.get(charset);
        if (stack == null) {
            stack = new SynchronizedStack<>();
            encoders.putIfAbsent(charset, stack);
            stack = encoders.get(charset);
        }
        conv = stack.pop();

        if (conv == null) {
            conv = createConverter(charset);
        }
    }


    private static B2CConverter createConverter(Charset charset) throws IOException {
        if (SecurityUtil.isPackageProtectionEnabled()) {
            try {
                return AccessController.doPrivileged(new PrivilegedCreateConverter(charset));
            } catch (PrivilegedActionException ex) {
                Exception e = ex.getException();
                if (e instanceof IOException) {
                    throw (IOException) e;
                } else {
                    throw new IOException(e);
                }
            }
        } else {
            return new B2CConverter(charset);
        }

    }


    @Override
    public void setByteBuffer(ByteBuffer buffer) {
        bb = buffer;
    }


    @Override
    public ByteBuffer getByteBuffer() {
        return bb;
    }


    @Override
    public void expand(int size) {
        // no-op
    }


    private boolean checkByteBufferEof() throws IOException {
        if (bb.remaining() == 0) {
            int n = realReadBytes();
            if (n < 0) {
                return true;
            }
        }
        return false;
    }

    private boolean checkCharBufferEof() throws IOException {
        if (cb.remaining() == 0) {
            int n = realReadChars();
            if (n < 0) {
                return true;
            }
        }
        return false;
    }

    private void clear(Buffer buffer) {
        buffer.rewind().limit(0);
    }

    private void makeSpace(int count) {
        int desiredSize = cb.limit() + count;
        if(desiredSize > readLimit) {
            desiredSize = readLimit;
        }

        if(desiredSize <= cb.capacity()) {
            return;
        }

        int newSize = 2 * cb.capacity();
        if(desiredSize >= newSize) {
            newSize= 2 * cb.capacity() + count;
        }

        if (newSize > readLimit) {
            newSize = readLimit;
        }

        CharBuffer tmp = CharBuffer.allocate(newSize);
        int oldPosition = cb.position();
        cb.position(0);
        tmp.put(cb);
        tmp.flip();
        tmp.position(oldPosition);
        cb = tmp;
        tmp = null;
    }


    private static class PrivilegedCreateConverter
            implements PrivilegedExceptionAction<B2CConverter> {

        private final Charset charset;

        public PrivilegedCreateConverter(Charset charset) {
            this.charset = charset;
        }

        @Override
        public B2CConverter run() throws IOException {
            return new B2CConverter(charset);
        }
    }
}
