/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.apache.oodt.cas.install;

//APACHE imports
import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

//JDK imports
import org.apache.oodt.cas.metadata.util.PathUtils;

import java.io.File;
import java.io.IOException;

//OODT imports
import static org.apache.oodt.cas.install.CASInstallDirMetKeys.*;

/**
 * Goal that unpackages a .tar.gz distribution of a CAS distro and installs it,
 * overriding configuration files and installing custom policy files, as
 * specified.
 * 
 * @goal install
 */
public class CASInstallDistMojo extends AbstractMojo {

    /**
     * Location of the CAS distribution to install, e.g.,
     * /path/to/cas-filemgr-{version}.tar.gz.
     * 
     * @parameter
     * @required
     */
    private File casDistributionFile;

    /**
     * Location of policy directories each containing XML-based CAS policy files
     * (e.g., <code>product-types.xml</code>,
     * <code>product-type-element-map.xml</code>, and
     * <code>elements.xml</code> for the CAS) that will be installed into the
     * {@link #casInstallationDir}/policy directory.
     * 
     * @parameter
     * 
     */
    private File[] customPolicyDirs;

    /**
     * Location of a directory containing a custom CAS configuration, e.g., a
     * filemgr.properties and/or a logging.properties file for filemgr that will
     * be copied into the {@link #casInstallationDir}/etc directory.
     * 
     * @parameter
     */
    private File customConfigurationDir;

    /**
     * The directory to which the plugin will install the CAS. Defaults to
     * /usr/local/${project.artifactId}-${project.version}, if not specified.
     * 
     * @parameter expression='/usr/local/${project.artifactId}-${project.version}'
     */
    private File casInstallationDir;

    /**
     * Location of custom jar files that you want to include in the
     * {@link #casInstallationDir}/lib directory.
     * 
     * @parameter
     */
    private File[] customLibs;

    /**
     * Files to do dynamic {@link PathUtils#replaceEnvVariables(String)} on.
     * 
     * @parameter
     */
    private EnvReplacer[] envVarReplaceFiles;

    /**
     * Script files to potentially overwrite and customize functionality for the
     * CAS bin scripts.
     * 
     * @parameter
     */
    private File[] customBinScripts;

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.maven.plugin.Mojo#execute()
     */
    public void execute() throws MojoExecutionException, MojoFailureException {

        if (casDistributionFile == null
                || (casDistributionFile != null && !casDistributionFile
                        .exists())) {
            throw new MojoExecutionException("the CAS distribution: ["
                    + casDistributionFile + "] does not exist!");
        }

        getLog().info(
                "unpackaging distro: [" + casDistributionFile + "] to: ["
                        + casInstallationDir + "]");
        try {
            AntDecorator.untarFile(casDistributionFile, casInstallationDir);
        } catch (IOException e) {
            throw new MojoExecutionException(
                    "an IO exception occured while untarring the CAS distribution: Message: "
                            + e.getMessage());
        }

        if (customPolicyDirs != null && customPolicyDirs.length > 0) {
            getLog().info(
                    "installing [" + customPolicyDirs.length
                            + "] custom policy dirs");

            // remove the default policy
            File policyDir = null;
            try {
                policyDir = new File(casInstallationDir.getCanonicalPath()
                        + File.separator + POLICY_DIR_NAME);
                AntDecorator.deleteAllFilesAndDir(policyDir);
            } catch (IOException e) {
                getLog().warn(
                        "IO exception when removing default policy from: ["
                                + policyDir + "]: Message: " + e.getMessage());
            }

            for (int i = 0; i < customPolicyDirs.length; i++) {
                getLog().info(
                        "Installing: [" + customPolicyDirs[i] + "] to: ["
                                + policyDir + "]");

                if (customPolicyDirs[i].exists()) {
                    try {
                        FileUtils.copyDirectoryToDirectory(customPolicyDirs[i],
                                policyDir);
                    } catch (IOException e) {
                        getLog().warn(
                                "error copying custom policy dir: ["
                                        + customPolicyDirs[i]
                                        + "] to policy dir: [" + policyDir
                                        + "]");
                    }
                }

            }

        }

        if (customConfigurationDir != null && customConfigurationDir.exists()) {

            try {
                File configDir = new File(casInstallationDir.getCanonicalPath()
                        + File.separator + CONFIG_DIR_NAME);

                // remove default config
                AntDecorator.deleteAllFilesAndDir(configDir);

                configDir.mkdir();

                // install custom config
                FileUtils
                        .copyDirectory(customConfigurationDir, configDir, true);

            } catch (IOException e) {
                getLog().warn(
                        "Unable to detect configuration dir: IO exception: "
                                + e.getMessage());
            }

        }

        if (customLibs != null && customLibs.length > 0) {
            getLog().info(
                    "installing [" + customLibs.length
                            + "] custom CAS libraries");

            File libDir = null;
            // get the lib dir
            try {
                libDir = new File(casInstallationDir.getCanonicalPath()
                        + File.separator + LIB_DIR_NAME);

            } catch (IOException e) {
                getLog().warn(
                        "Unable to detect lib dir: IO exception: "
                                + e.getMessage());
            }

            for (int i = 0; i < customLibs.length; i++) {
                getLog().info(
                        "installing [" + customLibs[i] + "] to "
                                + libDir.getAbsolutePath() + "]");
                try {
                    FileUtils.copyFileToDirectory(customLibs[i], libDir);
                } catch (IOException e) {
                    getLog().warn(
                            "IOException installing [" + customLibs[i]
                                    + "] to " + libDir.getAbsolutePath()
                                    + "]: Message: " + e.getMessage());
                }
            }
        }

        if (envVarReplaceFiles != null && envVarReplaceFiles.length > 0) {
            getLog().info(
                    "Replacing env vars on [" + envVarReplaceFiles.length
                            + "] files");

            for (int i = 0; i < envVarReplaceFiles.length; i++) {
                try {
                    envVarReplaceFiles[i].doEnvReplace();
                } catch (IOException e) {
                    getLog().warn(
                            "IOException while doing env replacement on: ["
                                    + envVarReplaceFiles[i].getFilepath()
                                    + "]: Message: " + e.getMessage());
                }
            }
        }

        if (customBinScripts != null && customBinScripts.length > 0) {
            getLog().info(
                    "installing [" + customBinScripts.length
                            + "] custom bin scripts");

            File binDir = null;

            try {
                binDir = new File(casInstallationDir.getCanonicalPath()
                        + File.separator + BIN_DIR_NAME);
            } catch (IOException e) {
                getLog().warn(
                        "Unable to detect bin dir: IO exception: Message: "
                                + e.getMessage());
            }

            for (int i = 0; i < customBinScripts.length; i++) {
                getLog().info(
                        "installing [" + customBinScripts[i] + "] to ["
                                + binDir + "]");
                try {
                    FileUtils.copyFileToDirectory(customBinScripts[i], binDir);
                    // now chmod it with exec perms
                    String custBinScriptFullPath = binDir + File.separator
                            + customBinScripts[i].getName();

                    getLog().info("fixing perms on ["+custBinScriptFullPath+"]");
                    AntDecorator.chmodFile(new File(custBinScriptFullPath),
                            "ugo+rx");
                } catch (IOException e) {
                    getLog().warn(
                            "unable to install [" + customBinScripts[i]
                                    + "] to [" + binDir
                                    + "]: IO exception: Message: "
                                    + e.getMessage());
                }
            }
        }

    }

}
