/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2004-2011 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.antmodular.jonasbase.jms;

import java.io.File;
import java.io.FileInputStream;
import java.util.Date;
import java.util.Properties;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Path;
import org.ow2.jonas.antmodular.bootstrap.JOnASAntTool;
import org.ow2.jonas.antmodular.jonasbase.bootstrap.BaseTaskItf;
import org.ow2.jonas.antmodular.jonasbase.bootstrap.JTask;
import org.ow2.jonas.antmodular.jonasbase.bootstrap.Replace;

/**
 * Allow to create/adapt the JMS resource adaptor.
 * @author Benoit Pelletier
 */
public class JmsRa extends JTask implements BaseTaskItf {

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

    /**
     * Name of the rar.
     */
    private static final String JORAM_RA_FOR_JONAS = "joram-jca-jonas";

    /**
     * RAConfig classname.
     */
    private static final String RACONFIG_CLASS = "org.ow2.jonas.generators.raconfig.RAConfig";

    /**
     * Default host name.
     */
    private static final String DEFAULT_HOST = "localhost";

    /**
     * Host name of the server.
     */
    private String serverHost = DEFAULT_HOST;

    /**
     * Default port number.
     */
    private static final String DEFAULT_PORT = "16010";

    /**
     * Port number of the server.
     */
    private String serverPort = DEFAULT_PORT;

    /**
     * Set the host name.
     * @param serverHost the host name
     */
    public void setServerHost(final String serverHost) {
        this.serverHost = serverHost;
    }

    /**
     * Set the port number.
     * @param serverPort the port nb
     */
    public void setServerPort(final String serverPort) {
        this.serverPort = serverPort;
    }

    /**
     * Execute this task.
     */
    @Override
    public void execute() {

        // Build new temp file for making a resource adaptor
        File tmpFile = new File(System.getProperty("java.io.tmpdir"), String.valueOf(new Date().getTime()));

        // Copy the RAR file from JONAS_ROOT to JONAS_BASE


        String rarFileName = JORAM_RA_FOR_JONAS + "-" + getJoramVersion() + ".rar";
        String rarDir = getMaven2Repository() + File.separator + "org" + File.separator + "ow2" + File.separator
                + "joram" + File.separator + JORAM_RA_FOR_JONAS + File.separator + getJoramVersion();
        String srcRarPathName = getJonasRoot().getPath() + File.separator + rarDir + File.separator + rarFileName;
        String dstRarPathName = getDestDir().getPath() + File.separator + rarDir + File.separator + rarFileName;

        Copy copy = new Copy();
        JOnASAntTool.configure(this, copy);
        copy.setTofile(new File(dstRarPathName));
        copy.setFile(new File(srcRarPathName));
        copy.setOverwrite(true);
        try {
            copy.execute();
        } catch (Exception rae) {
            rae.printStackTrace();
            JOnASAntTool.deleteAllFiles(tmpFile);
            throw new BuildException(INFO + "Cannot copy " + JORAM_RA_FOR_JONAS + " file : ", rae);
        }

        // Extract the jonas-ra.xml
        Expand jarTask = new Expand();
        JOnASAntTool.configure(this, jarTask);
        jarTask.setDest(tmpFile);
        jarTask.setSrc(new File(dstRarPathName));
        try {
            jarTask.execute();
        } catch (Exception rae) {
            rae.printStackTrace();
            JOnASAntTool.deleteAllFiles(tmpFile);
            throw new BuildException(INFO + "Cannot extract jonas-ra.xml with jar command : ", rae);
        }

        // update the jonas-ra.xml
        Replace replaceTask = new Replace();
        JOnASAntTool.configure(this, replaceTask);
        replaceTask.setFile(new File(tmpFile.getPath() + File.separator + "META-INF/jonas-ra.xml"));

        String token = "\r";
        String value = "";
        replaceTask.setToken(token);
        replaceTask.setValue(value);
        try {
            replaceTask.execute();
        } catch (Exception rae) {
            rae.printStackTrace();
            JOnASAntTool.deleteAllFiles(tmpFile);
            throw new BuildException(INFO + "Cannot replace port number in the jonas-ra.xml file : ", rae);
        }


        replaceTask = new Replace();
        JOnASAntTool.configure(this, replaceTask);
        replaceTask.setFile(new File(tmpFile.getPath() + File.separator + "META-INF/jonas-ra.xml"));

        String portToken = "<jonas-config-property-name>ServerPort</jonas-config-property-name>"
                         + "\n"
                         + "    <jonas-config-property-value></jonas-config-property-value>";
        String portValue = "<jonas-config-property-name>ServerPort</jonas-config-property-name>"
                         + "\n"
                         + "    <jonas-config-property-value>" + serverPort + "</jonas-config-property-value>";

        replaceTask.setToken(portToken);
        replaceTask.setValue(portValue);
        try {
            replaceTask.execute();
        } catch (Exception rae) {
            rae.printStackTrace();
            JOnASAntTool.deleteAllFiles(tmpFile);
            throw new BuildException(INFO + "Cannot replace port number in the jonas-ra.xml file : ", rae);
        }

        replaceTask = new Replace();
        JOnASAntTool.configure(this, replaceTask);
        replaceTask.setFile(new File(tmpFile.getPath() + File.separator + "META-INF/jonas-ra.xml"));

        String hostToken = "<jonas-config-property-name>HostName</jonas-config-property-name>"
                         + "\n"
                         + "    <jonas-config-property-value></jonas-config-property-value>";
        String hostValue = "<jonas-config-property-name>HostName</jonas-config-property-name>"
                         + "\n"
                         + "    <jonas-config-property-value>" + serverHost + "</jonas-config-property-value>";

        replaceTask.setToken(hostToken);
        replaceTask.setValue(hostValue);
        try {
            replaceTask.execute();
        } catch (Exception rae) {
            rae.printStackTrace();
            JOnASAntTool.deleteAllFiles(tmpFile);
            throw new BuildException(INFO + "Cannot replace host name in the jonas-ra.xml file : ", rae);
        }

        // update the archive
        Java raConfigTask = getBootstraptask("", false);

        // Add the ra-config Jar in the Java classpath path
        String clientJar = getJonasRoot().getPath() + File.separator + "lib" + File.separator + "client.jar";
        String raConfigJar = getJonasRoot().getPath() + File.separator + "lib" + File.separator + "jonas-generators-raconfig.jar";
        Path classpath = new Path(raConfigTask.getProject(), clientJar);
        classpath.append(new Path(raConfigTask.getProject(), raConfigJar));
        raConfigTask.setClasspath(classpath);

        JOnASAntTool.configure(this, raConfigTask);
        raConfigTask.clearArgs();
        raConfigTask.createArg().setValue(RACONFIG_CLASS);
        raConfigTask.createArg().setValue("-u");
        raConfigTask.createArg().setValue(tmpFile.getPath() + File.separator + "META-INF/jonas-ra.xml");
        raConfigTask.createArg().setValue(dstRarPathName);

        try {
            raConfigTask.execute();
        } catch (Exception rae) {
            rae.printStackTrace();
            throw new BuildException(INFO + "Cannot make a resource adaptor on RAConfig: ", rae);
        } finally {
            JOnASAntTool.deleteAllFiles(tmpFile);
        }

        log(INFO + "Setting host name to " + serverHost + ", port number to " + serverPort + " in the rar '" +
            dstRarPathName + "'.");
    }

    private String getJoramVersion() {
        Properties versions = new Properties();
        try {
            versions.load(new FileInputStream(new File(getJonasRoot(), "versions.properties")));
        } catch (Exception e) {
            throw new BuildException(INFO + "Cannot read versions.properties file: ", e);
        }
        return versions.getProperty("org.ow2.joram_joram-jca-jonas");
    }
}
