/*
 * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
 * Copyright 2004 The Apache Software Foundation
 *
 * Licensed 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.channels.InterruptedByTimeoutException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

import jakarta.servlet.ReadListener;
import jakarta.servlet.http.WebConnection;

import org.apache.catalina.ContainerEvent;
import org.apache.catalina.Context;
import org.apache.catalina.LogFacade;
import org.apache.catalina.Globals;
import org.glassfish.grizzly.ReadHandler;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.grizzly.http.util.ByteChunk.ByteInputChannel;
import org.glassfish.grizzly.http.util.CharChunk;

/**
 * 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 ByteInputChannel, CharChunk.CharInputChannel,
               CharChunk.CharOutputChannel {

    private static final Logger log = LogFacade.getLogger();
    private static final ResourceBundle rb = log.getResourceBundle();

    // -------------------------------------------------------------- Constants


    public static final int DEFAULT_BUFFER_SIZE = 8*1024;


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


    /**
     * Associated Grizzly request.
     */
    private Request grizzlyRequest;

    private org.glassfish.grizzly.http.io.InputBuffer grizzlyInputBuffer;

    private org.apache.catalina.connector.Request request;

    private ReadHandler readHandler = null;
    private boolean prevIsReady = true;
    private static final ThreadLocal<Boolean> IS_READY_SCOPE = new ThreadLocal<Boolean>();

    // ----------------------------------------------------------- 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 = new ByteChunk(size);
//        bb.setLimit(size);
//        bb.setByteInputChannel(this);
    }

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


    /**
     * Associated Grizzly request.
     *
     * @param grizzlyRequest Associated Grizzly request
     */
    public void setRequest(Request grizzlyRequest) {
        this.grizzlyRequest = grizzlyRequest;
        this.grizzlyInputBuffer = grizzlyRequest.getInputBuffer();
    }


    public void setRequest(org.apache.catalina.connector.Request request) {
        this.request = request;
    }


    /**
     * Get associated Grizzly request.
     *
     * @return the associated Grizzly request
     */
    public Request getRequest() {
        return this.grizzlyRequest;
    }


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


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

        if (log.isLoggable(Level.FINEST))
            log.log(Level.FINEST, "recycle()");

        grizzlyInputBuffer = null;
        grizzlyRequest = null;
        readHandler = null;
        prevIsReady = true;

    }


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


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


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


    /**
     * Reads new bytes in the byte chunk.
     *
     * @param cbuf Byte buffer to be written to the response
     * @param off Offset
     * @param len Length
     *
     * @throws IOException An underlying IOException occurred
     */
    public int realReadBytes(byte cbuf[], int off, int len)
    throws IOException {
        return grizzlyInputBuffer.read(cbuf, off, len);
    }


    public int readByte()
        throws IOException {
        if (grizzlyInputBuffer.isClosed())
            throw new IOException(rb.getString(LogFacade.STREAM_CLOSED));

        return grizzlyInputBuffer.readByte();
    }


    public int read(final byte[] b, final int off, final int len)
        throws IOException {
        if (grizzlyInputBuffer.isClosed())
            throw new IOException(rb.getString(LogFacade.STREAM_CLOSED));

        return grizzlyInputBuffer.read(b, off, len);
    }


    public boolean isFinished() {
        return grizzlyInputBuffer.isFinished();
    }


    public boolean isReady() {
        if (!prevIsReady) {
            return false;
        }

        boolean result = (grizzlyInputBuffer.available() > 0);
        if (!result) {
            if (readHandler != null) {
                prevIsReady = false; // Not data available
                IS_READY_SCOPE.set(Boolean.TRUE);
                try {
                    grizzlyInputBuffer.notifyAvailable(readHandler);
                } finally {
                    IS_READY_SCOPE.remove();
                }

            } else {
                prevIsReady = true;  // Allow next .isReady() call to check underlying inputStream
            }
        }

        return result;
    }


    public void setReadListener(ReadListener readListener) {
        if (readHandler != null) {
            throw new IllegalStateException(rb.getString(LogFacade.ALREADY_SET_READ_LISTENER));
        }

        if (!(request.isAsyncStarted() || request.isUpgrade())) {
            throw new IllegalStateException(rb.getString(LogFacade.NON_ASYNC_UPGRADE_READER_EXCEPTION));
        }

        readHandler = new ReadHandlerImpl(readListener);

        if (isReady()) {
            try {
                readHandler.onDataAvailable();
            } catch(Throwable t) {
                log.log(Level.WARNING, LogFacade.READ_LISTENER_ON_DATA_AVAILABLE_ERROR, t);
            }
        }
    }

    void disableReadHandler() {
        if (readHandler != null) {
            synchronized(readHandler) {
                readHandler.onError(new InterruptedByTimeoutException());
            }
        }
    }

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


    /**
     * Since the converter will use append, it is possible to get chars to
     * be removed from the buffer for "writing". Since the chars have already
     * been read before, they are ignored. If a mark was set, then the
     * mark is lost.
     */
    public void realWriteChars(char c[], int off, int len)
        throws IOException {
        // START OF SJSAS 6231069
//        initChar();
        // END OF SJSAS 6231069
//        markPos = -1;
    }


    public void setEncoding(final String encoding) {
        grizzlyInputBuffer.setDefaultEncoding(encoding);
    }


    public int realReadChars(final char cbuf[], final int off, final int len)
        throws IOException {

        return grizzlyInputBuffer.read(cbuf, off, len);

    }


    public int read()
        throws IOException {

        if (grizzlyInputBuffer.isClosed())
            throw new IOException(rb.getString(LogFacade.STREAM_CLOSED));

        return grizzlyInputBuffer.readChar();
    }


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

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


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

        if (grizzlyInputBuffer.isClosed())
            throw new IOException(rb.getString(LogFacade.STREAM_CLOSED));

        return grizzlyInputBuffer.read(cbuf, off, len);
    }


    public long skip(long n)
        throws IOException {

        if (grizzlyInputBuffer.isClosed())
            throw new IOException(rb.getString(LogFacade.STREAM_CLOSED));

        if (n < 0) {
            throw new IllegalArgumentException();
        }
        return grizzlyInputBuffer.skip(n, true);

    }


    public boolean ready()
        throws IOException {

        if (grizzlyInputBuffer.isClosed())
            throw new IOException(rb.getString(LogFacade.STREAM_CLOSED));

        return grizzlyInputBuffer.ready();
    }


    public boolean markSupported() {
        return true;
    }


    public void mark(int readAheadLimit)
        throws IOException {
        grizzlyInputBuffer.mark(readAheadLimit);
    }


    public void reset()
        throws IOException {

        if (grizzlyInputBuffer.isClosed())
            throw new IOException(rb.getString(LogFacade.STREAM_CLOSED));
        grizzlyInputBuffer.reset();
    }


    public void checkConverter()
        throws IOException {

        grizzlyInputBuffer.processingChars();

    }


    class ReadHandlerImpl implements ReadHandler {
        private ReadListener readListener = null;
        private volatile boolean disable = false;

        private ReadHandlerImpl(ReadListener listener) {
            readListener = listener;
        }

        @Override
        public void onDataAvailable() {
            if (disable) {
                return;
            }
            if (!Boolean.TRUE.equals(IS_READY_SCOPE.get())) {
                processDataAvailable();
            } else {
                AsyncContextImpl.getExecutorService().execute(new Runnable() {
                    @Override
                    public void run() {
                        processDataAvailable();
                    }
                });
            }
        }

        private void processDataAvailable() {
            ClassLoader oldCL;
            if (Globals.IS_SECURITY_ENABLED) {
                PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl();
                oldCL = AccessController.doPrivileged(pa);
            } else {
                oldCL = Thread.currentThread().getContextClassLoader();
            }

            try {
                Context context = request.getContext();
                ClassLoader newCL = context.getLoader().getClassLoader();
                if (Globals.IS_SECURITY_ENABLED) {
                    PrivilegedAction<Void> pa = new PrivilegedSetTccl(newCL);
                    AccessController.doPrivileged(pa);
                } else {
                    Thread.currentThread().setContextClassLoader(newCL);
                }

                synchronized(this) {
                    prevIsReady = true;
                    try {
                        context.fireContainerEvent(
                            ContainerEvent.BEFORE_READ_LISTENER_ON_DATA_AVAILABLE, readListener);
                        readListener.onDataAvailable();
                    } catch(Throwable t) {
                        disable = true;
                        readListener.onError(t);
                    } finally {
                        context.fireContainerEvent(
                            ContainerEvent.AFTER_READ_LISTENER_ON_DATA_AVAILABLE, readListener);
                    }
                }
            } finally {
                if (Globals.IS_SECURITY_ENABLED) {
                    PrivilegedAction<Void> pa = new PrivilegedSetTccl(oldCL);
                    AccessController.doPrivileged(pa);
                } else {
                    Thread.currentThread().setContextClassLoader(oldCL);
                }
            }
        }

        @Override
        public void onAllDataRead() {
            if (disable) {
                return;
            }
            if (!Boolean.TRUE.equals(IS_READY_SCOPE.get())) {
                processAllDataRead();
            } else {
                AsyncContextImpl.getExecutorService().execute(new Runnable() {
                    @Override
                    public void run() {
                        processAllDataRead();
                    }
                });
            }
        }

        private void processAllDataRead() {
            ClassLoader oldCL;
            if (Globals.IS_SECURITY_ENABLED) {
                PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl();
                oldCL = AccessController.doPrivileged(pa);
            } else {
                oldCL = Thread.currentThread().getContextClassLoader();
            }

            try {
                Context context = request.getContext();
                ClassLoader newCL = context.getLoader().getClassLoader();
                if (Globals.IS_SECURITY_ENABLED) {
                    PrivilegedAction<Void> pa = new PrivilegedSetTccl(newCL);
                    AccessController.doPrivileged(pa);
                } else {
                    Thread.currentThread().setContextClassLoader(newCL);
                }

                synchronized(this) {
                    prevIsReady = true;
                    try {
                        context.fireContainerEvent(
                            ContainerEvent.BEFORE_READ_LISTENER_ON_ALL_DATA_READ, readListener);
                        readListener.onAllDataRead();
                    } catch(Throwable t) {
                        disable = true;
                        readListener.onError(t);
                    } finally {
                        context.fireContainerEvent(
                            ContainerEvent.AFTER_READ_LISTENER_ON_ALL_DATA_READ, readListener);
                    }
                }
            } finally {
                if (Globals.IS_SECURITY_ENABLED) {
                    PrivilegedAction<Void> pa = new PrivilegedSetTccl(oldCL);
                    AccessController.doPrivileged(pa);
                } else {
                    Thread.currentThread().setContextClassLoader(oldCL);
                }
            }
        }

        @Override
        public void onError(final Throwable t) {
            if (disable) {
                return;
            }
            disable = true;

            if (!Boolean.TRUE.equals(IS_READY_SCOPE.get())) {
                processError(t);
            } else {
                AsyncContextImpl.getExecutorService().execute(new Runnable() {
                    @Override
                    public void run() {
                        processError(t);
                    }
                });
            }
        }

        private void processError(final Throwable t) {
            ClassLoader oldCL;
            if (Globals.IS_SECURITY_ENABLED) {
                PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl();
                oldCL = AccessController.doPrivileged(pa);
            } else {
                oldCL = Thread.currentThread().getContextClassLoader();
            }

            try {
                Context context = request.getContext();
                ClassLoader newCL = context.getLoader().getClassLoader();
                if (Globals.IS_SECURITY_ENABLED) {
                    PrivilegedAction<Void> pa = new PrivilegedSetTccl(newCL);
                    AccessController.doPrivileged(pa);
                } else {
                    Thread.currentThread().setContextClassLoader(newCL);
                }

                synchronized(this) {
                    // Get isUpgrade and WebConnection before calling onError
                    // Just in case onError will complete the async processing.
                    final boolean isUpgrade = request.isUpgrade();
                    final WebConnection wc = request.getWebConnection();

                    try {
                        context.fireContainerEvent(
                            ContainerEvent.BEFORE_READ_LISTENER_ON_ERROR, readListener);
                        readListener.onError(t);
                    } finally {
                        if (isUpgrade && wc != null) {
                            try {
                                wc.close();
                            } catch (Exception ignored) {
                            }
                        }
                        context.fireContainerEvent(
                            ContainerEvent.AFTER_READ_LISTENER_ON_ERROR, readListener);

                    }
                }
            } finally {
                if (Globals.IS_SECURITY_ENABLED) {
                    PrivilegedAction<Void> pa = new PrivilegedSetTccl(oldCL);
                    AccessController.doPrivileged(pa);
                } else {
                    Thread.currentThread().setContextClassLoader(oldCL);
                }
            }
        }
    }

    private static class PrivilegedSetTccl implements PrivilegedAction<Void> {

        private ClassLoader cl;

        PrivilegedSetTccl(ClassLoader cl) {
            this.cl = cl;
        }

        @Override
        public Void run() {
            Thread.currentThread().setContextClassLoader(cl);
            return null;
        }
    }

    private static class PrivilegedGetTccl
            implements PrivilegedAction<ClassLoader> {

        @Override
        public ClassLoader run() {
            return Thread.currentThread().getContextClassLoader();
        }
    }
}
