/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2005-2006 Bull S.A.S.
 * Contact: jonas-team@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Initial developer: Benoit Pelletier
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas.ant.cluster;

import java.io.File;
import java.util.Iterator;

import org.objectweb.jonas.ant.jonasbase.BaseTaskItf;
import org.objectweb.jonas.ant.jonasbase.WebContainer;
import org.objectweb.jonas.ant.jonasbase.web.Ajp;
import org.objectweb.jonas.ant.jonasbase.web.Cluster;
import org.objectweb.jonas.ant.jonasbase.web.Http;
import org.objectweb.jonas.ant.jonasbase.web.Tomcat;

/**
 * Define WebContainerCluster task
 * @author Benoit Pelletier
 */
public class WebContainerCluster extends ClusterTasks {

    /**
     * Info for the logger
     */
    private static final String INFO = "[WebContainerCluster] ";

    /**
     * Name of the container web : tomcat/jetty
     */
    private String name = null;

    /**
     * HTTP ports range
     */
    private String[] httpPortRange = null;

    /**
     * AJP ports range
     */
    private String[] ajpPortRange = null;

    /**
     * Sticky Session : true/false
     */
    private boolean stickySession = false;

    /**
     * mod_jk enabled : true/false
     */
    private boolean modjkEnabled = false;

    /**
     * mod_jk LB factor ports range
     */
    private String[] modJkLbFactorRange = null;

    /**
     * director enabled : true/false
     */
    private boolean directorEnabled = false;

    /**
     * Director ports range
     */
    private String[] directorPortRange = null;

    /**
     * director LB factor ports range
     */
    private String[] directorLbFactorRange = null;

    /**
     * multicast addr
     */
    private String clusterMcastAddr = null;

    /**
     * multicast port
     */
    private String clusterMcastPort = null;

    /**
     * Cluster Listen Port Range
     */
    private String[] clusterListenPortRange = null;

    /**
     * Cluster name
     */
    private String clusterName = null;

    /**
     * mod_jk directory
     */
    private String modjkDir = null;

    /**
     * mod_jk root directory
     */
    private String modjkRootDir = null;

    /**
     * director directory
     */
    private String directorDir = null;

    /**
     * Default constructor
     */
    public WebContainerCluster() {
        super();
    }

    /**
     * Set director directory
     * @param directorDir directory
     */
    public void setDirectorDir(String directorDir) {
        this.directorDir = directorDir;
    }

    /**
     * Set mod_jk enabled
     * @param enabled true/false
     */
    public void setModjkEnabled(boolean enabled) {
        this.modjkEnabled = enabled;
    }

    /**
     * Set director enabled
     * @param enabled true/false
     */
    public void setDirectorEnabled(boolean enabled) {
        this.directorEnabled = enabled;
    }

    /**
     * Set mod_jk directory
     * @param modjkDir directory
     */
    public void setModjkDir(String modjkDir) {
        this.modjkDir = modjkDir;
    }

    /**
     * Set mod_jk root directory
     * @param modjkRootDir directory
     */
    public void setModjkRootDir(String modjkRootDir) {
        this.modjkRootDir = modjkRootDir;
    }
    /**
     * Set clusterMcastAddr
     * @param clusterMcastAddr multicast address to set
     */
    public void setClusterMcastAddr(String clusterMcastAddr) {
        this.clusterMcastAddr = clusterMcastAddr;
    }

    /**
     * Set clusterMcastPort
     * @param clusterMcastPort multicast port to set
     */
    public void setClusterMcastPort(String clusterMcastPort) {
        this.clusterMcastPort = clusterMcastPort;
    }

    /**
     * Set Cluster listen ports range
     * @param clusterListenPortRange Cluster Listen ports range
     */
    public void setClusterListenPortRange(String clusterListenPortRange) {
        this.clusterListenPortRange = clusterListenPortRange.split(",");

    }

    /**
     * Set Cluster name
     * @param clusterName cluster name
     */
    public void setClusterName(String clusterName) {
        this.clusterName = clusterName;

    }

    /**
     * Set HTTP ports range
     * @param httpPortRange HTTP ports range
     */
    public void setHttpPortRange(String httpPortRange) {
        this.httpPortRange = httpPortRange.split(",");

    }

    /**
     * Set AJP ports range
     * @param ajpPortRange AJP ports range
     */
    public void setAjpPortRange(String ajpPortRange) {
        this.ajpPortRange = ajpPortRange.split(",");

    }

    /**
     * Set mod_jk lb factor range
     * @param modJkLbFactorRange load balancing factor range
     */
    public void setModJkLbFactorRange(String modJkLbFactorRange) {
        this.modJkLbFactorRange = modJkLbFactorRange.split(",");

    }

    /**
     * Set Director ports range
     * @param directorPortRange Director ports range
     */
    public void setDirectorPortRange(String directorPortRange) {
        this.directorPortRange = directorPortRange.split(",");

    }

    /**
     * Set director lb factor range
     * @param directorLbFactorRange load balancing factor range
     */
    public void setDirectorLbFactorRange(String directorLbFactorRange) {
        this.directorLbFactorRange = directorLbFactorRange.split(",");

    }

    /**
     * Set the name of the web container : jetty or tomcat
     * @param containerName jetty or tomcat
     */
    public void setName(String containerName) {

        this.name = containerName;
    }

    /**
     * Set the sticky session
     * @param stickySession true/false
     */
    public void setStickySession(boolean stickySession) {

        this.stickySession = stickySession;
    }

    /**
     * Generates the carol tasks for each JOnAS's instances
     */
    public void generatesTasks() {

        int portInd = 0;

        ModJk modJk = new ModJk();
        Director director = new Director();

        // creation of the mod_jk file
        modJk.setRootDir(modjkRootDir);
        modJk.setDir(modjkDir);
        modJk.createFiles();
        modJk.setStickySession(stickySession);

        // creation of the Director file
        director.createFile(directorDir);

        for (int i = getDestDirSuffixIndFirst(); i <= getDestDirSuffixIndLast(); i++) {

            String destDir = getDestDir(getDestDirPrefix(), i);

            log(INFO + "tasks generation for " + destDir);

            // creation of the WebContainer tasks
            WebContainer webContainer = new WebContainer();

            // FIXME still needed as we expect Tomcat only usage ?
            webContainer.setName(name);

            Tomcat tomcat = new Tomcat();
            Http http = new Http();
            http.setPort(httpPortRange[portInd]);
            tomcat.addConfiguredHttp(http);

            if (directorEnabled) {
                org.objectweb.jonas.ant.jonasbase.web.Director d = new org.objectweb.jonas.ant.jonasbase.web.Director();
                d.setPort(directorPortRange[portInd]);
                tomcat.addConfiguredDirector(d);
            }
            if (modjkEnabled) {
                Ajp ajp = new Ajp();
                ajp.setPort(ajpPortRange[portInd]);
                tomcat.addConfiguredAjp(ajp);
            }

            Cluster cluster = new Cluster();
            cluster.setListenPort(clusterListenPortRange[portInd]);
            cluster.setMcastAddr(clusterMcastAddr);
            cluster.setMcastPort(clusterMcastPort);
            cluster.setName(clusterName);
            tomcat.addConfiguredCluster(cluster);

            // mod_jk
            if (modjkEnabled) {
                String workerName = modJk.addWorker(ajpPortRange[portInd], modJkLbFactorRange[portInd]);
                tomcat.setJvmRoute(workerName);
            }

            webContainer.addConfiguredTomcat(tomcat);

            // director
            if (directorEnabled) {
                director.addAppServer(directorPortRange[portInd], directorLbFactorRange[portInd]);
            }

            // set destDir for each webContainer task
            for (Iterator it = webContainer.getTasks().iterator(); it.hasNext();) {
                BaseTaskItf task = (BaseTaskItf) it.next();
                task.setDestDir(new File(destDir));
            }

            addTasks(webContainer);

            portInd++;

        }

        if (modjkEnabled) {
            modJk.flushFiles();
            addTasks(modJk);
        }

        if (directorEnabled) {
            director.flushFile();
            addTasks(director);
        }
    }
}