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


import java.io.IOException;
import java.net.Socket;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import org.apache.ajp.Ajp13;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
import org.apache.tomcat.util.http.BaseRequest;

/**
 * @author Kevin Seguin
 * @version $Revision$ $Date$
 */

final class Ajp13Processor
    implements Lifecycle, Runnable {

    /**
     * A simple class to provide synchronized access
     * to a boolean.
     */
    private class Bool {

        private boolean b = false;

        Bool() {
        }
        
        Bool(boolean b) {
            this.b = b;
        }

        synchronized boolean value() {
            return b;
        }

        synchronized void set(boolean b) {
            this.b = b;
        }
    }

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


    /**
     * Construct a new Ajp13Processor associated with the specified connector.
     *
     * @param connector Ajp13Connector that owns this processor
     * @param id Identifier of this Ajp13Processor (unique per connector)
     * @param threadGroup The thread group any threads created by the processor
     *        should be in.
     */
    public Ajp13Processor(Ajp13Connector connector,
                          int id,
                          ThreadGroup threadGroup) {

	super();
	this.connector = connector;
	this.debug = connector.getDebug();
	this.id = id;
	this.request = (Ajp13Request) connector.createRequest();
        this.request.setConnector(connector);
        this.request.setConnector(connector);
	this.response = (Ajp13Response) connector.createResponse();
        this.response.setConnector(connector);
	this.threadName =
	  "Ajp13Processor[" + connector.getPort() + "][" + id + "]";
        this.threadGroup = threadGroup;

        this.logger.setConnector(connector);
        this.logger.setName(this.threadName);
    }


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

    private Ajp13Logger logger = new Ajp13Logger();
    private BaseRequest ajpRequest = new BaseRequest();

    /**
     * Is there a new socket available?
     */
    private boolean available = false;


    /**
     * The Ajp13Connector with which this processor is associated.
     */
    private Ajp13Connector connector = null;


    /**
     * The debugging detail level for this component.
     */
    private int debug = 0;


    /**
     * The identifier of this processor, unique per connector.
     */
    private int id = 0;


    /**
     * The lifecycle event support for this component.
     */
    private LifecycleSupport lifecycle = new LifecycleSupport(this);


    /**
     * The AJP13 request object we will pass to our associated container.
     */
    private Ajp13Request request = null;


    /**
     * The AJP13 response object we will pass to our associated container.
     */
    private Ajp13Response response = null;


    /**
     * The string manager for this package.
     */
    protected StringManager sm =
	StringManager.getManager(Constants.PACKAGE);


    /**
     * The socket we are currently processing a request for.  This object
     * is used for inter-thread communication only.
     */
    private Socket socket = null;


    /**
     * Has this component been started yet?
     */
    private boolean started = false;


    /**
     * The shutdown signal to our background thread
     */
    private Bool stopped = new Bool(true);

    /**
     * Are we currently handling a request?
     */
    private Bool handlingRequest = new Bool(false);


    /**
     * The background thread.
     */
    private Thread thread = null;


    /**
     * The name to register for the background thread.
     */
    private String threadName = null;


    /**
     * This processor's thread group.
     */
    private ThreadGroup threadGroup = null;


    /**
     * The thread synchronization object.
     */
    private Object threadSync = new Object();



    // -------------------------------------------------------- Package Methods


    /**
     * Process an incoming TCP/IP connection on the specified socket.  Any
     * exception that occurs during processing must be logged and swallowed.
     * <b>NOTE</b>:  This method is called from our Connector's thread.  We
     * must assign it to our own thread so that multiple simultaneous
     * requests can be handled.
     *
     * @param socket TCP socket to process
     */
    synchronized void assign(Socket socket) {

        // Wait for the Processor to get the previous Socket
        while (available) {
	    try {
	        wait();
	    } catch (InterruptedException e) {
	    }
        }

	// Store the newly available Socket and notify our thread
	this.socket = socket;
	available = true;
	notifyAll();

	if ((debug > 0) && (socket != null))
	    logger.log(" An incoming request is being assigned");

    }


    // -------------------------------------------------------- Private Methods


    /**
     * Await a newly assigned Socket from our Connector, or <code>null</code>
     * if we are supposed to shut down.
     */
    private synchronized Socket await() {

        // Wait for the Connector to provide a new Socket
        while (!available) {
	    try {
	        wait();
	    } catch (InterruptedException e) {
	    }
        }

	// Notify the Connector that we have received this Socket
	Socket socket = this.socket;
	available = false;
	notifyAll();

	if ((debug > 0) && (socket != null))
	    logger.log("  The incoming request has been awaited");

	return (socket);

    }

    /**
     * Parse and record the connection parameters related to this request.
     *
     * @param socket The socket on which we are connected
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a parsing error occurs
     */
    private void parseConnection(Socket socket)
        throws IOException, ServletException {

	if (debug > 1)
	    logger.log("  parseConnection: address=" + socket.getInetAddress() +
		", port=" + connector.getPort());
	request.setServerPort(connector.getPort());
        request.setSocket(socket);

    }

    /**
     * Process an incoming AJP13 request on the Socket that has been assigned
     * to this Processor.  Any exceptions that occur during processing must be
     * swallowed and dealt with.
     *
     * @param socket The socket on which we are connected to the client
     */
    private void process(Socket socket) {

        Ajp13 ajp13 = new Ajp13();
        ajp13.setDebug(debug);
        ajp13.setLogger(new org.apache.ajp.Logger() {
                public void log(String msg) {
                    logger.log("[Ajp13] " + msg);
                }
                
                public void log(String msg, Throwable t) {
                    logger.log("[Ajp13] " + msg, t);
                }
            });

        Ajp13InputStream input = new Ajp13InputStream(ajp13);
        Ajp13OutputStream output = new Ajp13OutputStream(ajp13);
        response.setAjp13(ajp13);

        try {
            ajp13.setSocket(socket);
        } catch (IOException e) {
            logger.log("process: ajp13.setSocket", e);
        }

        boolean moreRequests = true;
        String expectedSecret=connector.getSecret();
        
        boolean needAuth= ( expectedSecret != null );
        
        while (moreRequests && !stopped.value()) {
            
            int status = 0;
            try {
                if (debug > 0) {
                    logger.log("waiting on next request...");
                }
                
                status = ajp13.receiveNextRequest(ajpRequest);
                
                if (debug > 0) {
                    logger.log("received next request, status=" + status);
                }
            } catch (IOException e) {
                logger.log("process: ajp13.receiveNextRequest", e);
            }

            if( needAuth ) {
                String connSecret=ajp13.getSecret();
                if( connSecret == null ) {
                    logger.log( "Connection without password, " +
                                "tomcat is configured to require one" );
                    break;
                }
                if( ! connSecret.equals(expectedSecret) ) {
                    logger.log( "Connection with wrong password" );
                    break;
                }
                
                needAuth=false;
            }
            
            if (stopped.value()) {
                if (debug > 0) {
                    logger.log("process:  received request, but we're stopped");
                }
                break;
            }
            
            if( status==-2) {
                // special case - shutdown
                // XXX need better communication, refactor it
//                  if( !doShutdown(socket.getLocalAddress(),
//                                  socket.getInetAddress())) {
//                      moreRequests = false;
//                      continue;
//                  }
                break;
            }
            
			// Allready handled by low level proto, don't go farther
			if( status == 999 )
			{
				ajpRequest.recycle();
				request.recycle();

				// recycle ajp13 object
				ajp13.recycle();

				continue;
			}

			if( status != 200 )
				break;

            try {
                // set flag
                handlingRequest.set(true);

                boolean bad_request = false;

                // set up request
                try {
                    request.setAjpRequest(ajpRequest);
                } catch (IllegalArgumentException e) {
                    bad_request = true;
                }
                request.setResponse(response);
                request.setStream(input);
                
                // setup response
                response.setRequest(request);
                response.setStream(output);
                
                if (debug > 0) {
                    logger.log("invoking...");
                }

                if (!bad_request) {
                    try {
                        connector.getContainer().invoke(request, response);
                    } catch (IOException ioe) {
                        // Pass the IOException through
                        throw ioe;
                    } catch (Throwable e) {
                        // A throwable here could be caused by a Valve,
                        // Filter, or other component in the chain.
                        // Processing of the request failed, return an
                        // Internal Server Error
                        logger.log("process: invoke", e);
                        response.sendError
                            (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    }
                } else {
                    response.sendError
                        (HttpServletResponse.SC_BAD_REQUEST);
                }

                if (debug > 0) {
                    logger.log("done invoking, finishing request/response....");
                }

                response.finishResponse();
                request.finishRequest();

                if (debug > 0) {
                    logger.log("finished handling request.");
                }

            } catch (IOException ioe) {
                // Normally this catches a socket Broken Pipe caused by the
                // remote client aborting the request. Don't print the stack
                // trace in this case. Then let the Processor recycle.
                logger.log("process: IOException " + ioe.getMessage());
                moreRequests = false;
            } catch (Throwable e) {
                // Processing the request and sending the response failed.
                // We don't know what the state of the Ajp Connector socket
                // is in. Bail out and recycle the Processor.
                logger.log("process: finish", e);
                moreRequests = false;
            }

            // Recycling the request and the response objects
            if (debug > 0) {
                logger.log("recyling objects ...");
            }
            
            ajpRequest.recycle();
            request.recycle();
            response.recycle();

            // recycle ajp13 object
            ajp13.recycle();

            // reset flag
            handlingRequest.set(false);
        }
        
	try {
            if (debug > 0) {
                logger.log("closing ajp13 object...");
            }

            ajp13.close();

            if (debug > 0) {
                logger.log("ajp13 object closed.");
            }
	} catch (IOException e) {
	    logger.log("process: ajp13.close", e);
	}

	try {
            if (debug > 0) {
                logger.log("closing socket...");
            }

            socket.close();

            if (debug > 0) {
                logger.log("socket closed.");
            }
	} catch (IOException e) {
	    logger.log("process: socket.close", e);
	}
	socket = null;

        if (debug > 0) {
            logger.log("process:  done");
        }
    }


    // ---------------------------------------------- Background Thread Methods


    /**
     * The background thread that listens for incoming TCP/IP connections and
     * hands them off to an appropriate processor.
     */
    public void run() {

        // Process requests until we receive a shutdown signal
	while (!stopped.value()) {

	    // Wait for the next socket to be assigned
            if (debug > 0) {
                logger.log("waiting for next socket to be assigned...");
            }
	    Socket socket = await();
	    if (socket == null)
		continue;

            if (debug > 0) {
                logger.log("socket assigned.");
            }

	    // Process the request from this socket
	    process(socket);

	    // Finish up this request
            if (debug > 0) {
                logger.log("recycling myself ...");
            }
	    connector.recycle(this);
	}

	// Tell threadStop() we have shut ourselves down successfully
	synchronized (threadSync) {
	    threadSync.notifyAll();
	}

    }


    /**
     * Start the background processing thread.
     */
    private void threadStart() {

	logger.log(sm.getString("ajp13Processor.starting"));

        stopped.set(false);
	thread = new Thread(threadGroup, this, threadName);
	thread.setDaemon(true);
	thread.start();

	if (debug > 0)
	    logger.log(" Background thread has been started");

    }


    /**
     * Stop the background processing thread.
     */
    private void threadStop() {

	logger.log(sm.getString("ajp13Processor.stopping"));

	stopped.set(true);
        assign(null);
	synchronized (threadSync) {
	    try {
                if (handlingRequest.value()) {
                    if (debug > 0) {
                        logger.log
                            ("currentling handling a request, so waiting....");
                    }
                    threadSync.wait(5000);
                } else {
                    if (debug > 0) {
                        logger.log
                            ("not currently handling a request, not waiting.");
                    }
                }
	    } catch (InterruptedException e) {
		;
	    }
	}
	thread = null;

    }


    // ------------------------------------------------------ Lifecycle Methods


    /**
     * Add a lifecycle event listener to this component.
     *
     * @param listener The listener to add
     */
    public void addLifecycleListener(LifecycleListener listener) {

	lifecycle.addLifecycleListener(listener);

    }

    /**
     * Get the lifecycle listeners associated with this lifecycle. If this
     * Lifecycle has no listeners registered, a zero-length array is returned.
     */
    public LifecycleListener[] findLifecycleListeners() {
        return null; // FIXME: lifecycle.findLifecycleListeners();
    }


    /**
     * Remove a lifecycle event listener from this component.
     *
     * @param listener The listener to add
     */
    public void removeLifecycleListener(LifecycleListener listener) {

	lifecycle.removeLifecycleListener(listener);

    }


    /**
     * Start the background thread we will use for request processing.
     *
     * @exception LifecycleException if a fatal startup error occurs
     */
    public void start() throws LifecycleException {

	if (started)
	    throw new LifecycleException
		(sm.getString("ajp13Processor.alreadyStarted"));
	lifecycle.fireLifecycleEvent(START_EVENT, null);
	started = true;

	threadStart();

    }


    /**
     * Stop the background thread we will use for request processing.
     *
     * @exception LifecycleException if a fatal shutdown error occurs
     */
    public void stop() throws LifecycleException {

	if (!started)
	    throw new LifecycleException
		(sm.getString("ajp13Processor.notStarted"));
	lifecycle.fireLifecycleEvent(STOP_EVENT, null);
	started = false;

	threadStop();

    }


}
