/*
 * Copyright 1999,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.util;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import javax.servlet.http.HttpServletResponse;

/**
     * Encapsulates the knowledge of how to run a CGI script, given the
     * script's desired environment and (optionally) input/output streams
     *
     * <p>
     *
     * Exposes a <code>run</code> method used to actually invoke the
     * CGI.
     *
     * </p>
     * <p>
     *
     * The CGI environment and settings are derived from the information
     * passed to the constuctor.
     *
     * </p>
     * <p>
     *
     * The input and output streams can be set by the <code>setInput</code>
     * and <code>setResponse</code> methods, respectively.
     * </p>
     *
     * @author    Martin Dengler [root@martindengler.com]
     * @version   $Revision$, $Date$
     */
public class ProcessHelper {

    private static org.apache.commons.logging.Log log=
        org.apache.commons.logging.LogFactory.getLog( ProcessHelper.class );
    
    /** script/command to be executed */
    private String command = null;

    /** environment used when invoking the cgi script */
    private Hashtable env = null;

    /** working directory used when invoking the cgi script */
    private File wd = null;

    /** query parameters to be passed to the invoked script */
    private Hashtable params = null;

    /** stdin to be passed to cgi script */
    private InputStream stdin = null;

    /** response object used to set headers & get output stream */
    private HttpServletResponse response = null;

    /** boolean tracking whether this object has enough info to run() */
    private boolean readyToRun = false;

    /** the debugging detail level for this instance. */
    private int debug = 0;

    /** the time in ms to wait for the client to send us CGI input data */
    private int iClientInputTimeout;

    /**
     *  Creates a ProcessHelper and initializes its environment, working
     *  directory, and query parameters.
     *  <BR>
     *  Input/output streams (optional) are set using the
     *  <code>setInput</code> and <code>setResponse</code> methods,
     *  respectively.
     *
     * @param  command  string full path to command to be executed
     * @param  env      Hashtable with the desired script environment
     * @param  wd       File with the script's desired working directory
     * @param  params   Hashtable with the script's query parameters
     */
    public ProcessHelper(
        String command,
        Hashtable env,
        File wd,
        Hashtable params) {
        this.command = command;
        this.env = env;
        this.wd = wd;
        this.params = params;
        updateReadyStatus();
    }

    /**
     * Checks & sets ready status
     */
    protected void updateReadyStatus() {
        if (command != null
            && env != null
            && wd != null
            && params != null
            && response != null) {
            readyToRun = true;
        } else {
            readyToRun = false;
        }
    }

    /**
     * Gets ready status
     *
     * @return   false if not ready (<code>run</code> will throw
     *           an exception), true if ready
     */
    public boolean isReady() {
        return readyToRun;
    }

    /**
     * Sets HttpServletResponse object used to set headers and send
     * output to
     *
     * @param  response   HttpServletResponse to be used
     *
     */
    public void setResponse(HttpServletResponse response) {
        this.response = response;
        updateReadyStatus();
    }

    /**
     * Sets standard input to be passed on to the invoked cgi script
     *
     * @param  stdin   InputStream to be used
     *
     */
    public void setInput(InputStream stdin) {
        this.stdin = stdin;
        updateReadyStatus();
    }

    /**
     * Converts a Hashtable to a String array by converting each
     * key/value pair in the Hashtable to a String in the form
     * "key=value" (hashkey + "=" + hash.get(hashkey).toString())
     *
     * @param  h   Hashtable to convert
     *
     * @return     converted string array
     *
     * @exception  NullPointerException   if a hash key has a null value
     *
     */
    private String[] hashToStringArray(Hashtable h)
        throws NullPointerException {
        Vector v = new Vector();
        Enumeration e = h.keys();
        while (e.hasMoreElements()) {
            String k = e.nextElement().toString();
            v.add(k + "=" + h.get(k));
        }
        String[] strArr = new String[v.size()];
        v.copyInto(strArr);
        return strArr;
    }

    /**
     * Executes a process script with the desired environment, current working
     * directory, and input/output streams
     *
     * <p>
     * This implements the following CGI specification recommedations:
     * <UL>
     * <LI> Servers SHOULD provide the "<code>query</code>" component of
     *      the script-URI as command-line arguments to scripts if it
     *      does not contain any unencoded "=" characters and the
     *      command-line arguments can be generated in an unambiguous
     *      manner.
     * <LI> Servers SHOULD set the AUTH_TYPE metavariable to the value
     *      of the "<code>auth-scheme</code>" token of the
     *      "<code>Authorization</code>" if it was supplied as part of the
     *      request header.  See <code>getCGIEnvironment</code> method.
     * <LI> Where applicable, servers SHOULD set the current working
     *      directory to the directory in which the script is located
     *      before invoking it.
     * <LI> Server implementations SHOULD define their behavior for the
     *      following cases:
     *     <ul>
     *     <LI> <u>Allowed characters in pathInfo</u>:  This implementation
     *             does not allow ASCII NUL nor any character which cannot
     *             be URL-encoded according to internet standards;
     *     <LI> <u>Allowed characters in path segments</u>: This
     *             implementation does not allow non-terminal NULL
     *             segments in the the path -- IOExceptions may be thrown;
     *     <LI> <u>"<code>.</code>" and "<code>..</code>" path
     *             segments</u>:
     *             This implementation does not allow "<code>.</code>" and
     *             "<code>..</code>" in the the path, and such characters
     *             will result in an IOException being thrown;
     *     <LI> <u>Implementation limitations</u>: This implementation
     *             does not impose any limitations except as documented
     *             above.  This implementation may be limited by the
     *             servlet container used to house this implementation.
     *             In particular, all the primary CGI variable values
     *             are derived either directly or indirectly from the
     *             container's implementation of the Servlet API methods.
     *     </ul>
     * </UL>
     * </p>
     *
     * For more information, see java.lang.Runtime#exec(String command, 
     * String[] envp, File dir)
     *
     * @exception IOException if problems during reading/writing occur
     *
     */
    public void run() throws IOException {

        /*
         * REMIND:  this method feels too big; should it be re-written?
         */

        if (!isReady()) {
            throw new IOException(
                this.getClass().getName() + ": not ready to run.");
        }

        if (log.isDebugEnabled()) {
            log.debug("runCGI(envp=[" + env + "], command=" + command + ")");
        }

        if ((command.indexOf(File.separator + "." + File.separator) >= 0)
            || (command.indexOf(File.separator + "..") >= 0)
            || (command.indexOf(".." + File.separator) >= 0)) {
            throw new IOException(
                this.getClass().getName()
                    + "Illegal Character in CGI command "
                    + "path ('.' or '..') detected.  Not "
                    + "running CGI ["
                    + command
                    + "].");
        }

        /* original content/structure of this section taken from
         * http://developer.java.sun.com/developer/
         *                               bugParade/bugs/4216884.html
         * with major modifications by Martin Dengler
         */
        Runtime rt = null;
        BufferedReader commandsStdOut = null;
        BufferedReader commandsStdErr = null;
        BufferedOutputStream commandsStdIn = null;
        Process proc = null;
        byte[] bBuf = new byte[1024];
        char[] cBuf = new char[1024];
        int bufRead = -1;

        //create query arguments
        Enumeration paramNames = params.keys();
        StringBuffer cmdAndArgs = new StringBuffer(command);
        if (paramNames != null && paramNames.hasMoreElements()) {
            cmdAndArgs.append(" ");
            while (paramNames.hasMoreElements()) {
                String k = (String) paramNames.nextElement();
                String v = params.get(k).toString();
                if ((k.indexOf("=") < 0) && (v.indexOf("=") < 0)) {
                    cmdAndArgs.append(k);
                    cmdAndArgs.append("=");
                    v = java.net.URLEncoder.encode(v);
                    cmdAndArgs.append(v);
                    cmdAndArgs.append(" ");
                }
            }
        }

        String postIn = getPostInput(params);
        int contentLength =
            (postIn.length() + System.getProperty("line.separator").length());
        if ("POST".equals(env.get("REQUEST_METHOD"))) {
            env.put("CONTENT_LENGTH", new Integer(contentLength));
        }

        rt = Runtime.getRuntime();
        proc = rt.exec(cmdAndArgs.toString(), hashToStringArray(env), wd);

        /*
         * provide input to cgi
         * First  -- parameters
         * Second -- any remaining input
         */
        commandsStdIn = new BufferedOutputStream(proc.getOutputStream());
        if (log.isDebugEnabled()) {
            log.debug("runCGI stdin=[" + stdin + "], qs=" + env.get("QUERY_STRING"));
        }
        if ("POST".equals(env.get("REQUEST_METHOD"))) {
            if (log.isDebugEnabled()) {
                log.debug("runCGI: writing ---------------\n");
                log.debug(postIn);
                log.debug(
                    "runCGI: new content_length="
                        + contentLength
                        + "---------------\n");
            }
            commandsStdIn.write(postIn.getBytes());
        }
        if (stdin != null) {
            //REMIND: document this
            /* assume if nothing is available after a time, that nothing is
             * coming...
             */
            if (stdin.available() <= 0) {
                if (log.isDebugEnabled()) {
                    log.debug(
                        "runCGI stdin is NOT available ["
                            + stdin.available()
                            + "]");
                }
                try {
                    Thread.sleep(iClientInputTimeout);
                } catch (InterruptedException ignored) {
                }
            }
            if (stdin.available() > 0) {
                if (log.isDebugEnabled()) {
                    log.debug(
                        "runCGI stdin IS available ["
                            + stdin.available()
                            + "]");
                }
                bBuf = new byte[1024];
                bufRead = -1;
                try {
                    while ((bufRead = stdin.read(bBuf)) != -1) {
                        if (log.isDebugEnabled()) {
                            log.debug(
                                "runCGI: read ["
                                    + bufRead
                                    + "] bytes from stdin");
                        }
                        commandsStdIn.write(bBuf, 0, bufRead);
                    }
                    if (log.isDebugEnabled()) {
                        log.debug("runCGI: DONE READING from stdin");
                    }
                } catch (IOException ioe) {
                    log.error("runCGI: couldn't write all bytes.", ioe);
                }
            }
        }
        commandsStdIn.flush();
        commandsStdIn.close();

        /* we want to wait for the process to exit,  Process.waitFor()
         * is useless in our situation; see
         * http://developer.java.sun.com/developer/
         *                               bugParade/bugs/4223650.html
         */

        boolean isRunning = true;
        commandsStdOut =
            new BufferedReader(new InputStreamReader(proc.getInputStream()));
        commandsStdErr =
            new BufferedReader(new InputStreamReader(proc.getErrorStream()));
        BufferedWriter servletContainerStdout = null;

        try {
            if (response.getOutputStream() != null) {
                servletContainerStdout =
                    new BufferedWriter(
                        new OutputStreamWriter(response.getOutputStream()));
            }
        } catch (IOException ignored) {
            //NOOP: no output will be written
        }

        while (isRunning) {

            try {
                //read stderr first
                cBuf = new char[1024];
                while ((bufRead = commandsStdErr.read(cBuf)) != -1) {
                    if (servletContainerStdout != null) {
                        servletContainerStdout.write(cBuf, 0, bufRead);
                    }
                }

                //set headers
                String line = null;
                while (((line = commandsStdOut.readLine()) != null)
                    && !("".equals(line))) {
                    if (log.isDebugEnabled()) {
                        log.debug("runCGI: addHeader(\"" + line + "\")");
                    }
                    if (line.startsWith("HTTP")) {
                        //TODO: should set status codes (NPH support)
                        /*
                         * response.setStatus(getStatusCode(line));
                         */
                    } else {
                        response.addHeader(
                            line.substring(0, line.indexOf(":")).trim(),
                            line.substring(line.indexOf(":") + 1).trim());
                    }
                }

                //write output
                cBuf = new char[1024];
                while ((bufRead = commandsStdOut.read(cBuf)) != -1) {
                    if (servletContainerStdout != null) {
                        if (log.isDebugEnabled()) {
                            log.debug("runCGI: write(\"" + new String(cBuf) + "\")");
                        }
                        servletContainerStdout.write(cBuf, 0, bufRead);
                    }
                }

                if (servletContainerStdout != null) {
                    servletContainerStdout.flush();
                }

                proc.exitValue(); // Throws exception if alive

                isRunning = false;

            } catch (IllegalThreadStateException e) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ignored) {
                }
            }
        } //replacement for Process.waitFor()

    }

    /**
     * Gets a string for input to a POST cgi script
     *
     * @param  params   Hashtable of query parameters to be passed to
     *                  the CGI script
     * @return          for use as input to the CGI script
     */

    protected String getPostInput(Hashtable params) {
        String lineSeparator = System.getProperty("line.separator");
        Enumeration paramNames = params.keys();
        StringBuffer postInput = new StringBuffer("");
        StringBuffer qs = new StringBuffer("");
        if (paramNames != null && paramNames.hasMoreElements()) {
            while (paramNames.hasMoreElements()) {
                String k = (String) paramNames.nextElement();
                String v = params.get(k).toString();
                if ((k.indexOf("=") < 0) && (v.indexOf("=") < 0)) {
                    postInput.append(k);
                    qs.append(k);
                    postInput.append("=");
                    qs.append("=");
                    postInput.append(v);
                    qs.append(v);
                    postInput.append(lineSeparator);
                    qs.append("&");
                }
            }
        }
        qs.append(lineSeparator);
        return qs.append(postInput).toString();
    }

    public int getIClientInputTimeout() {
        return iClientInputTimeout;
    }

    public void setIClientInputTimeout(int iClientInputTimeout) {
        this.iClientInputTimeout = iClientInputTimeout;
    }
}
