/*
 *  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.coyote.ajp;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.jni.Socket;
import org.apache.tomcat.jni.Status;
import org.apache.tomcat.util.net.AprEndpoint;
import org.apache.tomcat.util.net.SocketWrapper;

/**
 * Processes AJP requests.
 *
 * @author Remy Maucherat
 * @author Henri Gomez
 * @author Dan Milstein
 * @author Keith Wannamaker
 * @author Kevin Seguin
 * @author Costin Manolache
 */
public class AjpAprProcessor extends AbstractAjpProcessor<Long> {

    private static final Log log = LogFactory.getLog(AjpAprProcessor.class);
    @Override
    protected Log getLog() {
        return log;
    }


    public AjpAprProcessor(int packetSize, AprEndpoint endpoint) {

        super(packetSize, endpoint);

        response.setOutputBuffer(new SocketOutputBuffer());

        // Allocate input and output buffers
        inputBuffer = ByteBuffer.allocateDirect(packetSize * 2);
        inputBuffer.limit(0);
        outputBuffer = ByteBuffer.allocateDirect(packetSize * 2);
    }


    /**
     * Direct buffer used for input.
     */
    protected final ByteBuffer inputBuffer;


    /**
     * Direct buffer used for output.
     */
    protected final ByteBuffer outputBuffer;


    @Override
    protected void registerForEvent(boolean read, boolean write) {
        socketWrapper.registerforEvent(-1, read, write);
    }

    @Override
    protected void resetTimeouts() {
        // NO-OP. The AJP APR/native connector only uses the timeout value on
        //        time SocketWrapper for async timeouts.
    }


    @Override
    protected void setupSocket(SocketWrapper<Long> socketWrapper) {
        long socketRef = socketWrapper.getSocket().longValue();
        Socket.setrbb(socketRef, inputBuffer);
        Socket.setsbb(socketRef, outputBuffer);
    }


    @Override
    protected void setTimeout(SocketWrapper<Long> socketWrapper,
            int timeout) throws IOException {
        Socket.timeoutSet(
                socketWrapper.getSocket().longValue(), timeout * 1000);
    }


    @Override
    protected int output(byte[] src, int offset, int length, boolean block)
            throws IOException {

        if (length == 0) {
            return 0;
        }

        outputBuffer.put(src, offset, length);

        int result = -1;

        if (socketWrapper.getSocket().longValue() != 0) {
            result = writeSocket(0, outputBuffer.position(), block);
            if (Status.APR_STATUS_IS_EAGAIN(-result)) {
                result = 0;
            }
            if (result < 0) {
                // There are no re-tries so clear the buffer to prevent a
                // possible overflow if the buffer is used again. BZ53119.
                outputBuffer.clear();
                throw new IOException(sm.getString("ajpprocessor.failedsend"));
            }
        }
        outputBuffer.clear();

        return result;
    }


    private int writeSocket(int pos, int len, boolean block) {

        Lock readLock = socketWrapper.getBlockingStatusReadLock();
        WriteLock writeLock = socketWrapper.getBlockingStatusWriteLock();
        long socket = socketWrapper.getSocket().longValue();

        boolean writeDone = false;
        int result = 0;
        readLock.lock();
        try {
            if (socketWrapper.getBlockingStatus() == block) {
                result = Socket.sendbb(socket, pos, len);
                writeDone = true;
            }
        } finally {
            readLock.unlock();
        }

        if (!writeDone) {
            writeLock.lock();
            try {
                socketWrapper.setBlockingStatus(block);
                // Set the current settings for this socket
                Socket.optSet(socket, Socket.APR_SO_NONBLOCK, (block ? 0 : 1));
                // Downgrade the lock
                readLock.lock();
                try {
                    writeLock.unlock();
                    result = Socket.sendbb(socket, pos, len);
                } finally {
                    readLock.unlock();
                }
            } finally {
                // Should have been released above but may not have been on some
                // exception paths
                if (writeLock.isHeldByCurrentThread()) {
                    writeLock.unlock();
                }
            }
        }

        return result;
    }


    @Override
    protected boolean read(byte[] buf, int pos, int n, boolean block)
            throws IOException {

        boolean nextReadBlocks = block;

        if (!block && inputBuffer.remaining() > 0) {
            nextReadBlocks = true;
        }

        if (inputBuffer.capacity() - inputBuffer.limit() <=
                n - inputBuffer.remaining()) {
            inputBuffer.compact();
            inputBuffer.limit(inputBuffer.position());
            inputBuffer.position(0);
        }
        int nRead;
        while (inputBuffer.remaining() < n) {
            nRead = readSocket(inputBuffer.limit(),
                    inputBuffer.capacity() - inputBuffer.limit(),
                    nextReadBlocks);
            if (nRead > 0) {
                inputBuffer.limit(inputBuffer.limit() + nRead);
                nextReadBlocks = true;
            } else if (-nRead == Status.EAGAIN) {
                return false;
            } else if ((-nRead) == Status.ETIMEDOUT || (-nRead) == Status.TIMEUP) {
                if (block) {
                    throw new SocketTimeoutException(
                            sm.getString("ajpprocessor.readtimeout"));
                } else {
                    // Attempting to read from the socket when the poller
                    // has not signalled that there is data to read appears
                    // to behave like a blocking read with a short timeout
                    // on OSX rather than like a non-blocking read. If no
                    // data is read, treat the resulting timeout like a
                    // non-blocking read that returned no data.
                    return false;
                }
            } else {
                throw new IOException(sm.getString("ajpprocessor.failedread"));
            }
        }

        inputBuffer.get(buf, pos, n);
        return true;
    }


    private int readSocket(int pos, int len, boolean block) {

        Lock readLock = socketWrapper.getBlockingStatusReadLock();
        WriteLock writeLock = socketWrapper.getBlockingStatusWriteLock();
        long socket = socketWrapper.getSocket().longValue();

        boolean readDone = false;
        int result = 0;
        readLock.lock();
        try {
            if (socketWrapper.getBlockingStatus() == block) {
                result = Socket.recvbb(socket, pos, len);
                readDone = true;
            }
        } finally {
            readLock.unlock();
        }

        if (!readDone) {
            writeLock.lock();
            try {
                socketWrapper.setBlockingStatus(block);
                // Set the current settings for this socket
                Socket.optSet(socket, Socket.APR_SO_NONBLOCK, (block ? 0 : 1));
                // Downgrade the lock
                readLock.lock();
                try {
                    writeLock.unlock();
                    result = Socket.recvbb(socket, pos, len);
                } finally {
                    readLock.unlock();
                }
            } finally {
                // Should have been released above but may not have been on some
                // exception paths
                if (writeLock.isHeldByCurrentThread()) {
                    writeLock.unlock();
                }
            }
        }

        return result;
    }


    /**
     * Recycle the processor.
     */
    @Override
    public void recycle(boolean socketClosing) {
        super.recycle(socketClosing);

        inputBuffer.clear();
        inputBuffer.limit(0);
        outputBuffer.clear();

    }
}
