/*
 * Copyright 2015 Andrej Petras.
 *
 * Licensed 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.lorislab.maven.release;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.lorislab.maven.release.model.SearchResultItem;
import org.lorislab.maven.release.util.FileSystemUtil;

/**
 * The update task.
 *
 * @author Andrej Petras
 */
@Mojo(name = "update", inheritByDefault = false, requiresDependencyResolution = ResolutionScope.COMPILE,
        threadSafe = true)
@Execute(goal = "update", phase = LifecyclePhase.PREPARE_PACKAGE)
public class PersistenceUpdateMojo extends AbstractPersistenceMojo {

    /**
     * The MAVEN project.
     */
    @Component
    protected MavenProject project;

    /**
     * The filter property file.
     */
    @Parameter(required = true)
    private String properties;

    /**
     * The create release directory flag.
     */
    @Parameter(required = false, defaultValue = "false")
    private boolean releaseDir;

    /**
     * The update artifact <groupId>:<artifactId>
     */
    @Parameter(required = true)
    private String updateArtifact;

    /**
     * Delete the backup files.
     */
    @Parameter(required = false, defaultValue = "true")
    private boolean deleteBackup;

    /**
     * {@inheritDoc }
     */
    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {

        // load the filter file
        final Map<String, String> values = loadProperties(properties);

        Artifact artifact = null;
        String[] ii = updateArtifact.split(":");
        String groupId = ii[0];
        String artifactId = ii[1];

        Set<Artifact> arts = (Set<Artifact>) project.getDependencyArtifacts();
        if (arts != null) {
            Iterator<Artifact> iter = arts.iterator();
            while (artifact == null && iter.hasNext()) {
                Artifact i = iter.next();
                if (i.getGroupId().equals(groupId) && i.getArtifactId().equals(artifactId)) {
                    artifact = i;
                }
            }
        }

        if (artifact != null) {
            release(values, artifact);
        } else {
            getLog().warn("Not update artifact found. Release artifact " + updateArtifact);
        }
    }

    private void release(final Map<String, String> values, Artifact artifact) {

        // build directory: target
        Path buildDir = Paths.get(project.getBuild().getDirectory());
        buildDir = FileSystemUtil.createDirectory(buildDir, "persistence-update");

        Path ap = artifact.getFile().toPath();
        Path releaseFile = buildDir.resolve(ap.getFileName());

        FileSystemUtil.copyFile(ap, releaseFile);

        // create the persistence temporary directory
        final Path tmpDir = FileSystemUtil.createDirectory(buildDir, "persistence-tmp");

        if ("jar".equals(artifact.getType()) || "war".equals(artifact.getType())) {

            final Path releasePersistenceFile = buildDir.resolve(ap.getFileName() + "-update");
            FileSystemUtil.copyFile(releaseFile, releasePersistenceFile);

            final Set<Path> changeFiles = new HashSet<>();
            SearchResultItem item = new SearchResultItem(releasePersistenceFile, project.getPackaging());
            updatePersistenceXml(item, changeFiles, tmpDir, values);

            if (!changeFiles.isEmpty()) {
                if (deleteBackup) {
                    FileSystemUtil.delete(releaseFile);                    
                } else {
                    final Path backupFile = buildDir.resolve(ap.getFileName() + "-backup");
                    FileSystemUtil.moveFile(releaseFile, backupFile);                    
                }
                FileSystemUtil.moveFile(releasePersistenceFile, releaseFile);
                
                if (releaseDir) {
                    Path releasePersistenceDir = buildDir.resolve(ap.getFileName() + "-update");
                    FileSystemUtil.unzip(releasePersistenceFile, releasePersistenceDir);
                }

            } else {
                getLog().info("No files containing the persistence.xml found.");
                FileSystemUtil.delete(releasePersistenceFile);
                FileSystemUtil.delete(tmpDir);
            }

        } else if ("ear".equals(artifact.getType())) {

            // unzip the release file to tmp directory: target/project-test
            Path releasePersistenceDir = buildDir.resolve(ap.getFileName() + "-update");
            FileSystemUtil.unzip(releaseFile, releasePersistenceDir);

            Set<SearchResultItem> files = FileSystemUtil.findFilesInDirectory(releasePersistenceDir, PATTERNS);

            final Set<Path> changeFiles = new HashSet<>();

            if (files != null && !files.isEmpty()) {
                for (final SearchResultItem file : files) {
                    updatePersistenceXml(file, changeFiles, tmpDir, values);
                }
            }

            if (!changeFiles.isEmpty()) {

                if (deleteBackup) {
                    FileSystemUtil.delete(releaseFile);
                } else {
                    final Path backupFile = buildDir.resolve(ap.getFileName() + "-backup");
                    FileSystemUtil.moveFile(releaseFile, backupFile);
                }

                // create new archive: target/project-test.ear
                FileSystemUtil.zip(releasePersistenceDir, releaseFile);

                if (!releaseDir) {
                    FileSystemUtil.delete(releasePersistenceDir);
                }
            } else {
                getLog().info("No files containing the persistence.xml found.");
            }
        } else {
            getLog().warn("Not supported packing type: " + artifact.getType());
        }

        FileSystemUtil.delete(tmpDir);
    }

}

@@ -2378,16 +2378,110 @@
 ackup;%0A%0A
+    /**%0A     * The output file name.%0A     */%0A    @Parameter%0A    private String filename;%0A    %0A
     /**%0A
@@ -3296,286 +3296,8 @@
  %7D%0A%0A
-        if (artifact != null) %7B%0A            release(values, artifact);%0A        %7D else %7B%0A            getLog().warn(%22Not update artifact found. Release artifact %22 + updateArtifact);%0A        %7D%0A    %7D%0A%0A    private void release(final Map%3CString, String%3E values, Artifact artifact) %7B%0A%0A
     
@@ -3477,24 +3477,203 @@
 -update%22);%0A%0A
+        if (filename == null %7C%7C filename.isEmpty()) %7B%0A            filename = artifact.getArtifactId() + %22-%22 + artifact.getVersion() + %22.%22 + artifact.getType();%0A        %7D%0A        %0A
         Path
@@ -3751,32 +3751,24 @@
 resolve(
-ap.getFileN
+filen
 ame
-()
 );%0A%0A    

Add output filename parameter.