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

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.FileSet;
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.DeployableSelector;

/**
 * Allow to create mail factory.
 * @author Florent Benoit
 */
public class DeployableTask extends JTask implements BaseTaskItf {

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

    /**
     * Deployables separator.
     */
    private static final String DEPSEPARATOR_PROPERTY = ",";

    /**
     * Exclude deployables.
     */
    private static final String TARGET_EXCLUDE_PROPERTY = "exclude";

    /**
     * Copy deployables.
     */
    private static final String TARGET_COPY_PROPERTY = "copy";
    /**
     * Source directory.
     */
    File f_srcDir;

    /**
     * Destination directory.
     */
    File f_dstDir;
    /**
     * Type of factory (Session or MimePartDataSource)
     */
    private String extension = null;

    /**
     * Name of the factory
     */
    private String values = null;

    /**
     * Directory to copy from.
     */
    private String srcDir = null;

    /**
     * Destination.
     */
    private String dstDir = null;

    /**
     * Target to execute. Possible values are : <code>copy, exclude</code>
     */
    private String target = null;


    public String getSrcDir() {
        return srcDir;
    }



    public void setSrcDir(final String sourceDir) {
        this.srcDir = sourceDir;
    }

    public String getExtension() {
        return extension;
    }

    public String getValues() {
        return values;
    }

    /**
     * Sets the recipient (MimePartDataSource)
     * @param mailTo recipient.
     */
    public void setValues(final String values) {
        this.values = values;
    }



    /**
     * Sets the extension
     * @param extension of the deployables
     */
    public void setExtension(final String extension) {
        this.extension = extension;
    }
    /**
     * Check the properties.
     */
    private void checkParameters() {
        try {
            // Get dest. dir.
            f_dstDir = new File(getDestDir().getPath(), this.dstDir);
            if (extension == null || values == null || target == null) {
                throw new BuildException(INFO + "Property 'extension' or 'values' is incorrect.");
            }
            if (TARGET_COPY_PROPERTY.equalsIgnoreCase(target)) {
             // Get source dir.
                f_srcDir = new File(this.srcDir);
                if ( !f_srcDir.exists()) {
                    throw new BuildException(INFO + "Property 'sourceDir'is incorrect.");
                }
            }else if(!TARGET_EXCLUDE_PROPERTY.equalsIgnoreCase(target)){
                throw new BuildException(INFO + "Unsupported target '" + target
                        + "'. Possible values are :'" + TARGET_COPY_PROPERTY + ", " + TARGET_EXCLUDE_PROPERTY + "'");
            }
            if ( !f_dstDir.exists()) {
                throw new BuildException(INFO + "Property 'destDir'is incorrect.");
            }
        } catch (Exception e) {
            throw new BuildException(INFO + "Properties are incorrect.");
        }
    }
    /**
     * Get the destination directory.
     * @return destination directory.
     */
    public String getDstDir() {
        return dstDir;
    }


    /**
     * Set the destination directory.
     * @param destDir destination directory.
     */
    public void setDstDir(final String destDir) {
        this.dstDir = destDir;
    }

    /**
     * Get the target to be executed.
     * @return the target
     */
    public String getTarget() {
        return target;
    }


    /**
     * Set the target to be executed.
     * @param target the target to be executed.
     */
    public void setTarget(final String target) {
        this.target = target;
    }



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

        checkParameters();
        List<String> deployables = new ArrayList<String>();
        parseDeployableValues(values, deployables);
        if (TARGET_COPY_PROPERTY.equalsIgnoreCase(target)) {
            log(INFO + "Copying Type: " + extension +   " values :" + deployables + " from " + f_srcDir.getAbsolutePath()
                    + " to " + f_dstDir.getAbsolutePath());
            Copy copyTask = new Copy();
            JOnASAntTool.configure(this, copyTask);
            copyTask.setFailOnError(true);
            copyTask.setTodir(f_dstDir);
            FileSet fset = new FileSet();
            fset.setDir(f_srcDir);
            DeployableSelector selector = new DeployableSelector(deployables);
            fset.add(selector);
            copyTask.addFileset(fset);
            copyTask.execute();

        }else {
            log(INFO + "Excluding Type: " + extension
                    + " values :" + values + " from " + f_dstDir.getAbsolutePath()
                    + " deployables: " + deployables);
            File toDelete = null;
            for(String fileName : deployables) {
                toDelete = new File(f_dstDir, fileName);
                if (toDelete.exists()) {
                    //Delete The file...
                    log(INFO + "Deleting " + toDelete.getAbsolutePath());
                    toDelete.delete();
                }
            }
        }



    }


    /**
     * get deployables from comma separated list.
     * @param values2Parse the values to parse.
     * @param deplList The list of deployables.
     * */
    private void parseDeployableValues(final String values2Parse, final List<String> deplList) {
        if (values2Parse != null) {
            int ind = values2Parse.indexOf(DEPSEPARATOR_PROPERTY);
            String dep = null;
            File depF = null;
            if (ind != -1) {
                dep = values2Parse.substring(0, ind) + "." + extension;
                depF = new File(f_srcDir.getAbsolutePath(), dep);
                if (depF.exists()) {
                    deplList.add(dep);
                }
                parseDeployableValues(values2Parse.substring(ind + 1, values2Parse.length()), deplList);
            }else {
                dep = values2Parse + "." + extension;
                if (TARGET_COPY_PROPERTY.equalsIgnoreCase(target)) {
                    depF = new File(f_srcDir.getAbsolutePath(), dep);
                }else {
                    depF = new File(f_dstDir.getAbsolutePath(), dep);
                }
                if (depF.exists()) {
                    deplList.add(dep);
                }
            }

        }
    }

}
