package com.github.alexcojocaru.mojo.elasticsearch.v2.step;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.UUID;

import org.apache.commons.io.FileUtils;

import com.github.alexcojocaru.mojo.elasticsearch.v2.ClusterConfiguration;
import com.github.alexcojocaru.mojo.elasticsearch.v2.InstanceConfiguration;
import com.github.alexcojocaru.mojo.elasticsearch.v2.configuration.ArtifactException;
import com.github.alexcojocaru.mojo.elasticsearch.v2.step.resolveartifact.ElasticsearchArtifactResolver;
import com.github.alexcojocaru.mojo.elasticsearch.v2.util.ArchiveUtil;
import com.github.alexcojocaru.mojo.elasticsearch.v2.util.FilesystemUtil;

/**
 * Download and unpack elasticsearch into the destination directory.
 *
 * @author Alex Cojocaru
 */
public class ResolveElasticsearchStep
        implements InstanceStep
{
    @Override
    public void execute(InstanceConfiguration config)
    {
        File unpackDirectory = null;
        try
        {
            File artifact = new ElasticsearchArtifactResolver(config.getClusterConfiguration())
                    .resolve();

            unpackDirectory = unpackToElasticsearchDirectory(artifact, config);

            setupElasticsearchConf(config);
        }
        catch (ArtifactException | IOException e)
        {
            throw new RuntimeException(e);
        }
        finally
        {
            cleanUp(unpackDirectory, config.getClusterConfiguration());
        }
    }

    private void cleanUp(File unpackDirectory, ClusterConfiguration config)
    {
        if (unpackDirectory != null)
        {
            try
            {
                FileUtils.deleteDirectory(unpackDirectory);
            }
            catch (IOException e)
            {
                config.getLog().error(
                        String.format(
                            "Could not delete Elasticsearch unpack directory : ",
                            unpackDirectory.getAbsolutePath()),
                        e);
            }
        }
    }

    private void setupElasticsearchConf(InstanceConfiguration config) throws IOException
    {
        String pathConf = config.getClusterConfiguration().getPathConf();
        if (pathConf != null && !pathConf.isEmpty())
        {
            // Merge the user-defined config directory with the default one
            // This allows user to omit some configuration files (jvm.options for instance)
            File baseDir = new File(config.getBaseDir());
            FileUtils.copyDirectory(new File(pathConf), new File(baseDir, "config"));
        }
    }

    private File unpackToElasticsearchDirectory(File artifact, InstanceConfiguration config)
            throws IOException
    {
        File unpackDirectory = getUnpackDirectory();
        ArchiveUtil.autodetectAndExtract(artifact, unpackDirectory);
        File baseDir = new File(config.getBaseDir());
        moveToElasticsearchDirectory(unpackDirectory, baseDir);

        return unpackDirectory;
    }

    private void moveToElasticsearchDirectory(File src, File dest) throws IOException
    {
        File[] files = src.listFiles(new FileFilter()
        {
            @Override
            public boolean accept(final File file)
            {
                return file.isDirectory();
            }
        });

        // should only be one
        FilesystemUtil.copyRecursively(files[0].toPath(), dest.toPath());
    }

    protected File getUnpackDirectory()
    {
        File tempDir = FilesystemUtil.getTempDirectory();
        File upackDirectory = new File(tempDir, UUID.randomUUID().toString());
        upackDirectory.mkdirs();
        return upackDirectory;
    }

}

@@ -151,14 +151,148 @@
 til.
-UUID;%0A
+Arrays;%0Aimport java.util.List;%0Aimport java.util.UUID;%0A%0Aimport com.google.common.collect.Lists;%0Aimport org.apache.commons.io.FileSystemUtils;
 %0Aimp
@@ -1381,16 +1381,59 @@
 onfig);%0A
+            keepExistingDataCheck(config);%0A
         
@@ -3875,10 +3875,488 @@
 %0A    %7D%0A%0A
+    private void keepExistingDataCheck(InstanceConfiguration config) throws IOException %7B%0A        File baseDir = new File(config.getBaseDir());%0A        File dataDir = FilesystemUtil.getDataDirectory(baseDir);%0A        File logsDir = FilesystemUtil.getLogsDirectory(baseDir);%0A%0A        if (Boolean.FALSE.equals(config.getClusterConfiguration().isKeepExistingData())) %7B%0A            FileUtils.deleteDirectory(dataDir);%0A            FileUtils.deleteDirectory(logsDir);%0A        %7D%0A    %7D%0A
 %7D%0A

delete data when keepExistingData flag is false