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

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
import org.apache.catalina.Host;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Server;


/**
    Base class for automatic jk based configurations based on
    the Tomcat server.xml settings and the war contexts
    initialized during startup.
    <p>
    This config interceptor is enabled by inserting a Config
    element in the <b>&lt;ContextManager&gt;</b> tag body inside
    the server.xml file like so:
    <pre>
    * < ContextManager ... >
    *   ...
    *   <<b>???Config</b> <i>options</i> />
    *   ...
    * < /ContextManager >
    </pre>
    where <i>options</i> can include any of the following attributes:
    <ul>
     <li><b>configHome</b> - default parent directory for the following paths.
                             If not set, this defaults to TOMCAT_HOME. Ignored
                             whenever any of the following paths is absolute.
                             </li>
     <li><b>workersConfig</b> - path to workers.properties file used by 
                                jk connector. If not set, defaults to
                                "conf/jk/workers.properties".</li>
     <li><b>jkLog</b> - path to log file to be used by jk connector.</li>
     <li><b>jkDebug</b> - Loglevel setting.  May be debug, info, error, or emerg.
                          If not set, defaults to emerg.</li>
     <li><b>jkWorker</b> The desired worker.  Must be set to one of the workers
                         defined in the workers.properties file. "ajp12", "ajp13"
                         or "inprocess" are the workers found in the default
                         workers.properties file. If not specified, defaults
                         to "ajp13" if an Ajp13Interceptor is in use, otherwise
                         it defaults to "ajp12".</li>
     <li><b>forwardAll</b> - If true, forward all requests to Tomcat. This helps
                             insure that all the behavior configured in the web.xml
                             file functions correctly.  If false, let Apache serve
                             static resources. The default is true.
                             Warning: When false, some configuration in
                             the web.xml may not be duplicated in Apache.
                             Review the mod_jk conf file to see what
                             configuration is actually being set in Apache.</li>
     <li><b>noRoot</b> - If true, the root context is not mapped to
                         Tomcat.  If false and forwardAll is true, all requests
                         to the root context are mapped to Tomcat. If false and
                         forwardAll is false, only JSP and servlets requests to
                         the root context are mapped to Tomcat. When false,
                         to correctly serve Tomcat's root context you may also
                         need to modify the web server to point it's home
                         directory to Tomcat's root context directory.
                         Otherwise some content, such as the root index.html,
                         may be served by the web server before the connector
                         gets a chance to claim the request and pass it to Tomcat.
                         The default is true.</li>
    </ul>
    <p>
    @author Costin Manolache
    @author Larry Isaacs
    @author Bill Barker
	@version $Revision$
 */
public class BaseJkConfig  implements LifecycleListener {

    private static org.apache.commons.logging.Log log=
        org.apache.commons.logging.LogFactory.getLog( BaseJkConfig.class );
    
    protected int debug=0;
    protected File configHome = null;
    protected File workersConfig = null;

    protected File jkLog = null;
    protected String jkDebug="emerg";
    protected String jkWorker = "ajp13";

    protected boolean noRoot=true;
    protected boolean forwardAll=true;

    protected String tomcatHome;
    protected boolean regenerate=false;
    protected boolean append=false;

    // -------------------- Tomcat callbacks --------------------


    // Auto-config should be able to react to dynamic config changes,
    // and regenerate the config.

    /** Generate the configuration - only when the server is
     *  completely initialized ( before starting )
     */
    public void lifecycleEvent(LifecycleEvent evt)
    {
	if(Lifecycle.START_EVENT.equals(evt.getType())) {
	   execute( evt );
	}
    }

    /** Generate configuration files.  Override with method to generate
        web server specific configuration.
     */
    public void execute(LifecycleEvent evt)
    {
	initProperties();
	PrintWriter mod_jk = null;
	try {
	    mod_jk = getWriter();
	} catch(IOException iex) {
	    log.warn("Unable to open config file", iex);
	    return;
	}
	Lifecycle who = evt.getLifecycle();
	if( who instanceof Server ) {
	    executeServer((Server)who, mod_jk);
	} else if ( who instanceof Host ) {
	    executeHost((Host)who, mod_jk);
	} else if( who instanceof Context ) {
	    executeContext((Context)who, mod_jk);
	}
	mod_jk.close();
    }
    /** Generate configuration files.  Override with method to generate
        web server specific configuration.
     */
    public void executeServer(Server svr, PrintWriter mod_jk) {
	if(! append ) {
	    if( ! generateJkHead(mod_jk) )
		return;
	    generateSSLConfig(mod_jk);
	    generateJkTail(mod_jk);
	}
    }

    /** Generate SSL options
     */
    protected void generateSSLConfig(PrintWriter mod_jk)
    {
    }
    /** Generate general options
     */
    protected boolean generateJkHead(PrintWriter mod_jk)
    {
	return true;
    }
    /** Generate general options
     */
    protected void generateJkTail(PrintWriter mod_jk)
    {
    }
    /** Generate Virtual Host start
     */
    protected void generateVhostHead(Host host, PrintWriter mod_jk) {
    }
    /** Generate Virtual Host end
     */
    protected void generateVhostTail(Host host, PrintWriter mod_jk) {
    }
    /** Generate configuration files.  Override with method to generate
        web server specific configuration.
     */
    protected void executeEngine(Engine egn, PrintWriter mod_jk) {
	Container [] children = egn.findChildren();
	for(int ii=0; ii < children.length; ii++) {
	    if( children[ii] instanceof Host ) {
		executeHost((Host)children[ii], mod_jk);
	    } else if( children[ii] instanceof Context ) {
		executeContext((Context)children[ii], mod_jk);
	    }
	}
    }
    /** Generate configuration files.  Override with method to generate
        web server specific configuration.
     */
    protected void executeHost(Host hst, PrintWriter mod_jk) {
	generateVhostHead(hst, mod_jk);
	Container [] children = hst.findChildren();
	for(int ii=0; ii < children.length; ii++) {
	    if(children[ii] instanceof Context) {
		executeContext((Context)children[ii],mod_jk);
	    }
	}
	generateVhostTail(hst, mod_jk);
    }
    /**
        executes the ApacheConfig interceptor. This method generates apache
        configuration files for use with  mod_jk.
        <p>
        @param context a Context object.
	@param mod_jk Writer for output.
    */
    public void executeContext(Context context, PrintWriter mod_jk){

	if(context.getPath().length() > 0 || ! noRoot ) {
	    String docRoot = context.getServletContext().getRealPath("/");
	    if( forwardAll || docRoot == null)
		generateStupidMappings( context, mod_jk );
	    else
		generateContextMappings( context, mod_jk);
	}
    }
    protected void generateStupidMappings(Context context, PrintWriter mod_jk){
    }
    protected void generateContextMappings(Context context, PrintWriter mod_jk){
    }
    /** Get the output Writer.  Override with method to generate
        web server specific configuration.
     */
    protected PrintWriter getWriter() throws IOException {
	return null;
    }
    /** Get the host associated with this Container (if any).
     */
    protected Host getHost(Container child) {
	while(child != null && ! (child instanceof Host) ) {
	    child = child.getParent();
	}
	return (Host)child;
    }

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

    /** Append to config file.
     *  Set to <code>true</code> if the config information should be 
     *  appended.
     */
    public void setAppend(boolean apnd) {
	append = apnd;
    }
    /** If false, we'll try to generate a config that will
     *  let apache serve static files.
     *  The default is true, forward all requests in a context
     *  to tomcat.
     */
    public void setForwardAll( boolean b ) {
        forwardAll=b;
    }

    /** Special option - do not generate mappings for the ROOT
        context. The default is true, and will not generate the mappings,
        not redirecting all pages to tomcat (since /* matches everything).
        This means that the web server's root remains intact but isn't
        completely servlet/JSP enabled. If the ROOT webapp can be configured
        with the web server serving static files, there's no problem setting
        this option to false. If not, then setting it true means the web
        server will be out of picture for all requests.
    */
    public void setNoRoot( boolean b ) {
        noRoot=b;
    }
    
    /**
        set a path to the parent directory of the
        conf folder.  That is, the parent directory
        within which path setters would be resolved against,
        if relative.  For example if ConfigHome is set to "/home/tomcat"
        and regConfig is set to "conf/mod_jk.conf" then the resulting 
        path used would be: 
        "/home/tomcat/conf/mod_jk.conf".</p>
        <p>
        However, if the path is set to an absolute path,
        this attribute is ignored.
        <p>
        If not set, execute() will set this to TOMCAT_HOME.
        <p>
        @param dir - path to a directory
    */
    public void setConfigHome(String dir){
        if( dir==null ) return;
        File f=new File(dir);
        if(!f.isDirectory()){
            throw new IllegalArgumentException(
                "BaseConfig.setConfigHome(): "+
                "Configuration Home must be a directory! : "+dir);
        }
        configHome = f;
    }

    /**
        set a path to the workers.properties file.
        @param path String path to workers.properties file
    */
    public void setWorkersConfig(String path){
        workersConfig= (path==null?null:new File(path));
    }

    /**
        set the path to the log file
        @param path String path to a file
    */
    public void setJkLog(String path){
        jkLog= ( path==null?null:new File(path));
    }

    /** Set the verbosity level
        ( use debug, error, etc. ) If not set, no log is written.
     */
    public void setJkDebug( String level ) {
        jkDebug=level;
    }

    /**
        Set the AJP worker.
        @param worker The worker name
     */
    public void setJkWorker(String worker){
        jkWorker = worker;
    }

    // -------------------- Initialize/guess defaults --------------------

    /** Initialize defaults for properties that are not set
        explicitely
    */
    protected void initProperties() {
        tomcatHome = System.getProperty("catalina.home");
        File tomcatDir = new File(tomcatHome);
        if(configHome==null){
            configHome=tomcatDir;
        }
    }

    // -------------------- Config Utils  --------------------


    /** Add an extension mapping. Override with method to generate
        web server specific configuration
     */
    protected boolean addExtensionMapping( String ctxPath, String ext,
					 PrintWriter pw )
    {
	return true;
    }
    
    
    /** Add a fulling specified mapping.  Override with method to generate
        web server specific configuration
     */
    protected boolean addMapping( String fullPath, PrintWriter pw ) {
	return true;
    }

    // -------------------- General Utils --------------------

    protected String getAbsoluteDocBase(Context context)
    {
	// Calculate the absolute path of the document base
	String docBase = context.getServletContext().getRealPath("/");
	docBase = docBase.substring(0,docBase.length()-1);
	if (!isAbsolute(docBase)){
	    docBase = tomcatHome + "/" + docBase;
	}
	docBase = patch(docBase);
        return docBase;
    }

    // ------------------ Grabbed from FileUtil -----------------
    public static File getConfigFile( File base, File configDir, String defaultF )
    {
        if( base==null )
            base=new File( defaultF );
        if( ! base.isAbsolute() ) {
            if( configDir != null )
                base=new File( configDir, base.getPath());
            else
                base=new File( base.getAbsolutePath()); //??
        }
        File parent=new File(base.getParent());
        if(!parent.exists()){
            if(!parent.mkdirs()){
                throw new RuntimeException(
                    "Unable to create path to config file :"+
                    base.getAbsolutePath());
            }
        }
        return base;
    }
    public static String patch(String path) {
        String patchPath = path;

        // Move drive spec to the front of the path
        if (patchPath.length() >= 3 &&
            patchPath.charAt(0) == '/'  &&
            Character.isLetter(patchPath.charAt(1)) &&
            patchPath.charAt(2) == ':') {
            patchPath=patchPath.substring(1,3)+"/"+patchPath.substring(3);
        }

        // Eliminate consecutive slashes after the drive spec
	if (patchPath.length() >= 2 &&
            Character.isLetter(patchPath.charAt(0)) &&
            patchPath.charAt(1) == ':') {
            char[] ca = patchPath.replace('/', '\\').toCharArray();
            char c;
            StringBuffer sb = new StringBuffer();

            for (int i = 0; i < ca.length; i++) {
                if ((ca[i] != '\\') ||
                    (ca[i] == '\\' &&
                        i > 0 &&
                        ca[i - 1] != '\\')) {
                    if (i == 0 &&
                        Character.isLetter(ca[i]) &&
                        i < ca.length - 1 &&
                        ca[i + 1] == ':') {
                        c = Character.toUpperCase(ca[i]);
                    } else {
                        c = ca[i];
                    }

                    sb.append(c);
                }
            }

            patchPath = sb.toString();
        }

	// fix path on NetWare - all '/' become '\\' and remove duplicate '\\'
	if (System.getProperty("os.name").startsWith("NetWare") &&
	    path.length() >=3 &&
	    path.indexOf(':') > 0) {
	    char[] ca = patchPath.replace('/', '\\').toCharArray();
	    StringBuffer sb = new StringBuffer();

	    for (int i = 0; i < ca.length; i++) {
		if ((ca[i] != '\\') ||
		    (ca[i] == '\\' && i > 0 && ca[i - 1] != '\\')) {
		    sb.append(ca[i]);
		}
	    }
	    patchPath = sb.toString();
	}

        return patchPath;
    }

    public static boolean isAbsolute( String path ) {
	// normal file
	if( path.startsWith("/" ) ) return true;

	if( path.startsWith(File.separator ) ) return true;

	// win c:
	if (path.length() >= 3 &&
            Character.isLetter(path.charAt(0)) &&
            path.charAt(1) == ':')
	    return true;

	// NetWare volume:
	if (System.getProperty("os.name").startsWith("NetWare") &&
	    path.length() >=3 &&
	    path.indexOf(':') > 0)
	    return true;

	return false;
    }

    protected void log(String msg) {
        log.info(msg);
    }
}
