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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;

import org.apache.tools.ant.BuildException;
import org.ow2.jonas.ant.BootstrapTask;

/**
 * Defines a common task.
 * @author Florent Benoit
 */
public class JTask extends BootstrapTask implements BaseTaskItf {

    /**
     * Property separators (4 spaces).
     */
    public static final String SEPARATORS = "    ";

    /**
     * configuration file used.
     */
    private String configurationFile = null;

    /**
     * Information for the logger.
     */
    private String logInfo = null;

    /**
     * Destination directory (JONAS_BASE).
     */
    private File destDir = null;

    /**
     * Sets the configuration file.
     * @param configurationFile The configurationFile to set.
     */
    public void setConfigurationFile(final String configurationFile) {
        this.configurationFile = configurationFile;
    }

    /**
     * @param destDir The destDir to set.
     */
    public void setDestDir(final File destDir) {
        this.destDir = destDir;
    }

    /**
     * Gets logger info (to be displayed).
     * @return logger info
     * @see org.ow2.jonas.ant.jonasbase.BaseTaskItf#getLogInfo()
     */
    public String getLogInfo() {
        return logInfo;
    }

    /**
     * Set the info to be displayed by the logger.
     * @param logInfo information to be displayed
     * @see org.ow2.jonas.ant.jonasbase.BaseTaskItf#setLogInfo(String)
     */
    public void setLogInfo(final String logInfo) {
        this.logInfo = logInfo;
    }

    /**
     * Gets the destination directory.
     * @return the destination directory
     */
    public File getDestDir() {
        return destDir;
    }

    /**
     * Write properties object to a file with some logging info.
     * @param info header for logging
     * @param props Properties to write
     * @param f file for writing
     */
    protected void writePropsToFile(final String info,
                                    final Properties props,
                                    final File f) {
        OutputStream fOut = null;
        try {
            fOut = new FileOutputStream(f);
        } catch (FileNotFoundException e) {
            throw new BuildException(info + "File is invalid", e);
        }

        // Write properties to file
        try {
            props.store(fOut, "");
            fOut.close();
        } catch (IOException ioe) {
            throw new BuildException(info + "Error while writing properties", ioe);
        }

    }

    /**
     * Add a value for a specific property in a configuration file.
     * The separator uses between the property name and the property value is the default separator value.
     * @param info text to be displayed for header
     * @param confDir configuration directory (can be JONAS_BASE/conf)
     * @param confFile configuration file (can be jonas.properties)
     * @param property which must be found in confFile
     * @param name value for the property to add
     * @param add if true, add it, else replace
     */
    protected void changeValueForKey(final String info,
                                     final String confDir,
                                     final String confFile,
                                     final String property,
                                     final String name,
                                     final boolean add) {
        changeValueForKey(info, confDir, confFile, property, name, SEPARATORS, add);
    }

    /**
     * Add a value for a specific property in a configuration file.
     * @param info text to be displayed for header
     * @param confDir configuration directory (can be JONAS_BASE/conf)
     * @param confFile configuration file (can be jonas.properties)
     * @param property which must be found in confFile
     * @param name value for the property to add
     * @param separators separator using between the property name and the property value
     * @param add if true, add it, else replace
     */
    protected void changeValueForKey(final String info,
                                     final String confDir,
                                     final String confFile,
                                     final String property,
                                     final String name,
                                     final String separators,
                                     final boolean add) {


        if (name == null) {
            log(info + "Ignoring property '" + property + "' in " + confFile
                    + " as the value is not provided.");
            return;
        }

        // Read current value
        Properties currentProps = new Properties();
        File f = null;
        try {
            f = new File(confDir + File.separator + confFile);
            currentProps.load(new FileInputStream(f));
        } catch (Exception e) {
            throw new BuildException(
                    "Cannot load current properties for file '" + f + "'.", e);
        }

        String valueOfProperty = currentProps.getProperty(property);

        // Now, add/replace mail value
        JReplace propertyReplace = new JReplace();
        propertyReplace.setProject(getProject());
        propertyReplace.setConfigurationFile(confFile);
        propertyReplace.setDestDir(new File(getDestDir().getPath()));
        if (valueOfProperty == null || valueOfProperty.length() == 0) {
            propertyReplace.setToken(property);
            propertyReplace.setValue(property + separators + name);
        } else if (!add) {
            propertyReplace.setToken(property + separators + valueOfProperty);
            propertyReplace.setValue(property + separators + name);
        } else {
            valueOfProperty = valueOfProperty.trim();
            propertyReplace.setToken(property + separators + valueOfProperty);
            valueOfProperty += ", " + name;
            String replaceVal = property + separators + valueOfProperty;
            replaceVal = replaceVal.trim();
            propertyReplace.setValue(replaceVal);
        }
        if (add) {
            log(info + "Adding '" + name + "' in " + confFile
                    + " file to property '" + property + "'.");
        } else {
            log(info + "Replacing the property '" + property + " : "+name+"' in "
                    + confFile + " file .");
        }
        propertyReplace.execute();
    }

    /**
     * @return the configurationFile.
     */
    protected String getConfigurationFile() {
        return configurationFile;
    }
}
