/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2005-2008 Bull S.A.S.
 * Contact: jonas-team@ow2.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
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.ant.cluster;

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

import org.ow2.jonas.ant.jonasbase.BaseTaskItf;
import org.ow2.jonas.ant.jonasbase.WebContainer;
import org.ow2.jonas.ant.jonasbase.web.Ajp;
import org.ow2.jonas.ant.jonasbase.web.Cluster;
import org.ow2.jonas.ant.jonasbase.web.Http;
import org.ow2.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;

    /**
     * director directory.
     */
    private String ondemandRedirectPort = null;

    /**
     * director directory.
     */
    private boolean ondemandEnabled = true;

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

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

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

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

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

    /**
     * Set ondemand enabled.
     * @param enabled true/false
     */
    public void setOndemandEnabled(final boolean enabled) {
        this.ondemandEnabled = enabled;
    }

    /**
     * Set mod_jk directory.
     * @param modjkDir directory
     */
    public void setOndemandRedirectPort(final String redirectport) {
        this.ondemandRedirectPort = redirectport;
    }

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

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

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

    }

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

    }

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

    }

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

    }

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

    }

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

    }

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

    }

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

        this.name = containerName;
    }

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

        this.stickySession = stickySession;
    }

    /**
     * Generates the WebContainer tasks for each JOnAS's instances.
     */
    @Override
    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.ow2.jonas.ant.jonasbase.web.Director d = new org.ow2.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]);
            }

            if (ondemandEnabled) {
                // set the redirect port
                webContainer.setOndemandredirectPort(ondemandRedirectPort);
            }
            webContainer.setOndemandenabled(Boolean.toString(ondemandEnabled));

            // set destDir for each webContainer task
            for (Iterator it = webContainer.getTasks().iterator(); it.hasNext();) {
                BaseTaskItf task = (BaseTaskItf) it.next();
                task.setDestDir(new File(destDir));
                // Disabling, wondering the use case of JONAS-67 
                //modJk.addWorkerFile(destDir + File.separator + "conf");
            }

            addTasks(webContainer);

            portInd++;

        }

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

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