/*
 * 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$
     * @deprecated
     */
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;
    }
}
