/*
 * 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.commons.release.plugin.mojos;

import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.file.PathUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.release.plugin.SharedFunctions;
import org.apache.commons.release.plugin.velocity.HeaderHtmlVelocityDelegate;
import org.apache.commons.release.plugin.velocity.ReadmeHtmlVelocityDelegate;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
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.project.MavenProject;
import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.ScmFileSet;
import org.apache.maven.scm.command.add.AddScmResult;
import org.apache.maven.scm.command.checkin.CheckInScmResult;
import org.apache.maven.scm.command.checkout.CheckOutScmResult;
import org.apache.maven.scm.manager.BasicScmManager;
import org.apache.maven.scm.manager.ScmManager;
import org.apache.maven.scm.provider.ScmProvider;
import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
import org.apache.maven.scm.provider.svn.svnexe.SvnExeScmProvider;
import org.apache.maven.scm.repository.ScmRepository;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.crypto.SettingsDecrypter;

/**
 * This class checks out the dev distribution location, copies the distributions into that directory
 * structure under the <code>target/commons-release-plugin/scm</code> directory. Then commits the
 * distributions back up to SVN. Also, we include the built and zipped site as well as the RELEASE-NOTES.txt.
 *
 * @since 1.0
 */
@Mojo(name = "stage-distributions",
        defaultPhase = LifecyclePhase.DEPLOY,
        threadSafe = true,
        aggregator = true)
public class CommonsDistributionStagingMojo extends AbstractMojo {

    /** The name of file generated from the README.vm velocity template to be checked into the dist svn repo. */
    private static final String README_FILE_NAME = "README.html";

    /** The name of file generated from the HEADER.vm velocity template to be checked into the dist svn repo. */
    private static final String HEADER_FILE_NAME = "HEADER.html";

    /** The name of the signature validation shell script to be checked into the dist svn repo. */
    private static final String SIGNATURE_VALIDATOR_NAME = "signature-validator.sh";
    /**
     * The {@link MavenProject} object is essentially the context of the maven build at
     * a given time.
     */
    @Parameter(defaultValue = "${project}", required = true)
    private MavenProject project;

    /**
     * The {@link File} that contains a file to the root directory of the working project. Typically
     * this directory is where the <code>pom.xml</code> resides.
     */
    @Parameter(defaultValue = "${basedir}")
    private File baseDir;

    /** The location to which the site gets built during running <code>mvn site</code>. */
    @Parameter(defaultValue = "${project.build.directory}/site", property = "commons.siteOutputDirectory")
    private File siteDirectory;

    /**
     * The main working directory for the plugin, namely <code>target/commons-release-plugin</code>, but
     * that assumes that we're using the default maven <code>${project.build.directory}</code>.
     */
    @Parameter(defaultValue = "${project.build.directory}/commons-release-plugin", property = "commons.outputDirectory")
    private File workingDirectory;

    /**
     * The location to which to check out the dist subversion repository under our working directory, which
     * was given above.
     */
    @Parameter(defaultValue = "${project.build.directory}/commons-release-plugin/scm",
            property = "commons.distCheckoutDirectory")
    private File distCheckoutDirectory;

    /**
     * The location of the RELEASE-NOTES.txt file such that multi-module builds can configure it.
     */
    @Parameter(defaultValue = "${basedir}/RELEASE-NOTES.txt", property = "commons.releaseNotesLocation")
    private File releaseNotesFile;

    /**
     * A boolean that determines whether or not we actually commit the files up to the subversion repository.
     * If this is set to {@code true}, we do all but make the commits. We do checkout the repository in question
     * though.
     */
    @Parameter(property = "commons.release.dryRun", defaultValue = "false")
    private Boolean dryRun;

    /**
     * The url of the subversion repository to which we wish the artifacts to be staged. Typically this would need to
     * be of the form: <code>scm:svn:https://dist.apache.org/repos/dist/dev/commons/foo/version-RC#</code>. Note. that
     * the prefix to the substring <code>https</code> is a requirement.
     */
    @Parameter(defaultValue = "", property = "commons.distSvnStagingUrl")
    private String distSvnStagingUrl;

    /**
     * A parameter to generally avoid running unless it is specifically turned on by the consuming module.
     */
    @Parameter(defaultValue = "false", property = "commons.release.isDistModule")
    private Boolean isDistModule;

    /**
     * The release version of the artifact to be built.
     */
    @Parameter(property = "commons.release.version")
    private String commonsReleaseVersion;

    /**
     * The RC version of the release. For example the first voted on candidate would be "RC1".
     */
    @Parameter(property = "commons.rc.version")
    private String commonsRcVersion;

    /**
     * The ID of the server (specified in settings.xml) which should be used for dist authentication.
     * This will be used in preference to {@link #username}/{@link #password}.
     */
    @Parameter(property = "commons.distServer")
    private String distServer;

    /**
     * The username for the distribution subversion repository. This is typically your Apache id.
     */
    @Parameter(property = "user.name")
    private String username;

    /**
     * The password associated with {@link CommonsDistributionStagingMojo#username}.
     */
    @Parameter(property = "user.password")
    private String password;

    /**
     * Maven {@link Settings}.
     */
    @Parameter(defaultValue = "${settings}", readonly = true, required = true)
    private Settings settings;

    /**
     * Maven {@link SettingsDecrypter} component.
     */
    @Component
    private SettingsDecrypter settingsDecrypter;

    /**
     * A subdirectory of the dist directory into which we are going to stage the release candidate. We
     * build this up in the {@link CommonsDistributionStagingMojo#execute()} method. And, for example,
     * the directory should look like <code>https://dist.apache.org/repos/dist/dev/commons/text/1.4-RC1</code>.
     */
    private File distRcVersionDirectory;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        if (!isDistModule) {
            getLog().info("This module is marked as a non distribution "
                    + "or assembly module, and the plugin will not run.");
            return;
        }
        if (StringUtils.isEmpty(distSvnStagingUrl)) {
            getLog().warn("commons.distSvnStagingUrl is not set, the commons-release-plugin will not run.");
            return;
        }
        if (!workingDirectory.exists()) {
            getLog().info("Current project contains no distributions. Not executing.");
            return;
        }
        getLog().info("Preparing to stage distributions");
        try {
            final ScmManager scmManager = new BasicScmManager();
            scmManager.setScmProvider("svn", new SvnExeScmProvider());
            final ScmRepository repository = scmManager.makeScmRepository(distSvnStagingUrl);
            final ScmProvider provider = scmManager.getProviderByRepository(repository);
            final SvnScmProviderRepository providerRepository = (SvnScmProviderRepository) repository
                    .getProviderRepository();
            SharedFunctions.setAuthentication(
                    providerRepository,
                    distServer,
                    settings,
                    settingsDecrypter,
                    username,
                    password
            );
            distRcVersionDirectory =
                    new File(distCheckoutDirectory, commonsReleaseVersion + "-" + commonsRcVersion);
            if (!distCheckoutDirectory.exists()) {
                SharedFunctions.initDirectory(getLog(), distCheckoutDirectory);
            }
            final ScmFileSet scmFileSet = new ScmFileSet(distCheckoutDirectory);
            getLog().info("Checking out dist from: " + distSvnStagingUrl);
            final CheckOutScmResult checkOutResult = provider.checkOut(repository, scmFileSet);
            if (!checkOutResult.isSuccess()) {
                throw new MojoExecutionException("Failed to checkout files from SCM: "
                        + checkOutResult.getProviderMessage() + " [" + checkOutResult.getCommandOutput() + "]");
            }
            final File copiedReleaseNotes = copyReleaseNotesToWorkingDirectory();
            copyDistributionsIntoScmDirectoryStructureAndAddToSvn(copiedReleaseNotes,
                    provider, repository);
            final List<File> filesToAdd = new ArrayList<>();
            listNotHiddenFilesAndDirectories(distCheckoutDirectory, filesToAdd);
            if (!dryRun) {
                final ScmFileSet fileSet = new ScmFileSet(distCheckoutDirectory, filesToAdd);
                final AddScmResult addResult = provider.add(
                        repository,
                        fileSet
                );
                if (!addResult.isSuccess()) {
                    throw new MojoExecutionException("Failed to add files to SCM: " + addResult.getProviderMessage()
                            + " [" + addResult.getCommandOutput() + "]");
                }
                getLog().info("Staging release: " + project.getArtifactId() + ", version: " + project.getVersion());
                final CheckInScmResult checkInResult = provider.checkIn(
                        repository,
                        fileSet,
                        "Staging release: " + project.getArtifactId() + ", version: " + project.getVersion()
                );
                if (!checkInResult.isSuccess()) {
                    getLog().error("Committing dist files failed: " + checkInResult.getCommandOutput());
                    throw new MojoExecutionException(
                            "Committing dist files failed: " + checkInResult.getCommandOutput()
                    );
                }
                getLog().info("Committed revision " + checkInResult.getScmRevision());
            } else {
                getLog().info("[Dry run] Would have committed to: " + distSvnStagingUrl);
                getLog().info(
                        "[Dry run] Staging release: " + project.getArtifactId() + ", version: " + project.getVersion());
            }
        } catch (final ScmException e) {
            getLog().error("Could not commit files to dist: " + distSvnStagingUrl, e);
            throw new MojoExecutionException("Could not commit files to dist: " + distSvnStagingUrl, e);
        }
    }

    /**
     * Lists all directories and files to a flat list.
     * @param directory {@link File} containing directory to list
     * @param files a {@link List} of {@link File} to which to append the files.
     */
    private void listNotHiddenFilesAndDirectories(final File directory, final List<File> files) {
        // Get all the files and directories from a directory.
        final File[] fList = directory.listFiles();
        for (final File file : fList) {
            if (file.isFile() && !file.isHidden()) {
                files.add(file);
            } else if (file.isDirectory() && !file.isHidden()) {
                files.add(file);
                listNotHiddenFilesAndDirectories(file, files);
            }
        }
    }

    /**
     * A utility method that takes the <code>RELEASE-NOTES.txt</code> file from the base directory of the
     * project and copies it into {@link CommonsDistributionStagingMojo#workingDirectory}.
     *
     * @return the RELEASE-NOTES.txt file that exists in the <code>target/commons-release-notes/scm</code>
     *         directory for the purpose of adding it to the scm change set in the method
     *         {@link CommonsDistributionStagingMojo#copyDistributionsIntoScmDirectoryStructureAndAddToSvn(File,
     *         ScmProvider, ScmRepository)}.
     * @throws MojoExecutionException if an {@link IOException} occurs as a wrapper so that maven
     *                                can properly handle the exception.
     */
    private File copyReleaseNotesToWorkingDirectory() throws MojoExecutionException {
        SharedFunctions.initDirectory(getLog(), distRcVersionDirectory);
        getLog().info("Copying RELEASE-NOTES.txt to working directory.");
        final File copiedReleaseNotes = new File(distRcVersionDirectory, releaseNotesFile.getName());
        SharedFunctions.copyFile(getLog(), releaseNotesFile, copiedReleaseNotes);
        return copiedReleaseNotes;
    }

    /**
     * Copies the list of files at the root of the {@link CommonsDistributionStagingMojo#workingDirectory} into
     * the directory structure of the distribution staging repository. Specifically:
     * <ul>
     *   <li>root:
     *     <ul>
     *         <li>site</li>
     *         <li>site.zip</li>
     *         <li>RELEASE-NOTES.txt</li>
     *         <li>source:
     *           <ul>
     *             <li>-src artifacts....</li>
     *           </ul>
     *         </li>
     *         <li>binaries:
     *           <ul>
     *             <li>-bin artifacts....</li>
     *           </ul>
     *         </li>
     *     </ul>
     *   </li>
     * </ul>
     *
     * @param copiedReleaseNotes is the RELEASE-NOTES.txt file that exists in the
     *                           <code>target/commons-release-plugin/scm</code> directory.
     * @param provider is the {@link ScmProvider} that we will use for adding the files we wish to commit.
     * @param repository is the {@link ScmRepository} that we will use for adding the files that we wish to commit.
     * @return a {@link List} of {@link File}'s in the directory for the purpose of adding them to the maven
     *         {@link ScmFileSet}.
     * @throws MojoExecutionException if an {@link IOException} occurs so that Maven can handle it properly.
     */
    private List<File> copyDistributionsIntoScmDirectoryStructureAndAddToSvn(final File copiedReleaseNotes,
                                                                             final ScmProvider provider,
                                                                             final ScmRepository repository)
            throws MojoExecutionException {
        final List<File> workingDirectoryFiles = Arrays.asList(workingDirectory.listFiles());
        final List<File> filesForMavenScmFileSet = new ArrayList<>();
        final File scmBinariesRoot = new File(distRcVersionDirectory, "binaries");
        final File scmSourceRoot = new File(distRcVersionDirectory, "source");
        SharedFunctions.initDirectory(getLog(), scmBinariesRoot);
        SharedFunctions.initDirectory(getLog(), scmSourceRoot);
        File copy;
        for (final File file : workingDirectoryFiles) {
            if (file.getName().contains("src")) {
                copy = new File(scmSourceRoot,  file.getName());
                SharedFunctions.copyFile(getLog(), file, copy);
                filesForMavenScmFileSet.add(file);
            } else if (file.getName().contains("bin")) {
                copy = new File(scmBinariesRoot,  file.getName());
                SharedFunctions.copyFile(getLog(), file, copy);
                filesForMavenScmFileSet.add(file);
            } else if (StringUtils.containsAny(file.getName(), "scm", "sha256.properties", "sha512.properties")) {
                getLog().debug("Not copying scm directory over to the scm directory because it is the scm directory.");
                //do nothing because we are copying into scm
            } else {
                copy = new File(distCheckoutDirectory.getAbsolutePath(),  file.getName());
                SharedFunctions.copyFile(getLog(), file, copy);
                filesForMavenScmFileSet.add(file);
            }
        }
        filesForMavenScmFileSet.addAll(buildReadmeAndHeaderHtmlFiles());
        filesForMavenScmFileSet.add(copySignatureValidatorScriptToScmDirectory());
        filesForMavenScmFileSet.addAll(copySiteToScmDirectory());
        return filesForMavenScmFileSet;
    }

    /**
     * Copies our <code>signature-validator.sh</code> script into
     * <code>${basedir}/target/commons-release-plugin/scm/signature-validator.sh</code>.
     *
     * @return the {@link File} for the signature-validator.sh
     * @throws MojoExecutionException if an error occurs while the resource is being copied
     */
    private File copySignatureValidatorScriptToScmDirectory() throws MojoExecutionException {
        final Path scmTargetPath = Paths.get(distRcVersionDirectory.toString(), SIGNATURE_VALIDATOR_NAME);
        final String name = "/resources/" + SIGNATURE_VALIDATOR_NAME;
        // The source can be in a local file or inside a jar file.
        try {
            PathUtils.copyFile(getClass().getResource(name), scmTargetPath);
        } catch (final Exception e) {
            throw new MojoExecutionException(String.format("Failed to copy '%s' to '%s'", name, scmTargetPath), e);
        }
        return scmTargetPath.toFile();
    }

    /**
     * Copies <code>${basedir}/target/site</code> to <code>${basedir}/target/commons-release-plugin/scm/site</code>.
     *
     * @return the {@link List} of {@link File}'s contained in
     *         <code>${basedir}/target/commons-release-plugin/scm/site</code>, after the copy is complete.
     * @throws MojoExecutionException if the site copying fails for some reason.
     */
    private List<File> copySiteToScmDirectory() throws MojoExecutionException {
        if (!siteDirectory.exists()) {
            getLog().error("\"mvn site\" was not run before this goal, or a siteDirectory did not exist.");
            throw new MojoExecutionException(
                    "\"mvn site\" was not run before this goal, or a siteDirectory did not exist."
            );
        }
        final File siteInScm = new File(distRcVersionDirectory, "site");
        try {
            FileUtils.copyDirectory(siteDirectory, siteInScm);
        } catch (final IOException e) {
            throw new MojoExecutionException("Site copying failed", e);
        }
        return new ArrayList<>(FileUtils.listFiles(siteInScm, null, true));
    }

    /**
     * Builds up <code>README.html</code> and <code>HEADER.html</code> that reside in following.
     * <ul>
     *     <li>distRoot
     *     <ul>
     *         <li>binaries/HEADER.html (symlink)</li>
     *         <li>binaries/README.html (symlink)</li>
     *         <li>source/HEADER.html (symlink)</li>
     *         <li>source/README.html (symlink)</li>
     *         <li>HEADER.html</li>
     *         <li>README.html</li>
     *     </ul>
     *     </li>
     * </ul>
     * @return the {@link List} of created files above
     * @throws MojoExecutionException if an {@link IOException} occurs in the creation of these
     *                                files fails.
     */
    private List<File> buildReadmeAndHeaderHtmlFiles() throws MojoExecutionException {
        final List<File> headerAndReadmeFiles = new ArrayList<>();
        final File headerFile = new File(distRcVersionDirectory, HEADER_FILE_NAME);
        //
        // HEADER file
        //
        try (Writer headerWriter = new OutputStreamWriter(Files.newOutputStream(headerFile.toPath()),
                StandardCharsets.UTF_8)) {
            HeaderHtmlVelocityDelegate.builder().build().render(headerWriter);
        } catch (final IOException e) {
            final String message = "Could not build HEADER html file " + headerFile;
            getLog().error(message, e);
            throw new MojoExecutionException(message, e);
        }
        headerAndReadmeFiles.add(headerFile);
        //
        // README file
        //
        final File readmeFile = new File(distRcVersionDirectory, README_FILE_NAME);
        try (Writer readmeWriter = new OutputStreamWriter(Files.newOutputStream(readmeFile.toPath()),
                StandardCharsets.UTF_8)) {
            // @formatter:off
            final ReadmeHtmlVelocityDelegate readmeHtmlVelocityDelegate = ReadmeHtmlVelocityDelegate.builder()
                    .withArtifactId(project.getArtifactId())
                    .withVersion(project.getVersion())
                    .withSiteUrl(project.getUrl())
                    .build();
            // @formatter:on
            readmeHtmlVelocityDelegate.render(readmeWriter);
        } catch (final IOException e) {
            final String message = "Could not build README html file " + readmeFile;
            getLog().error(message, e);
            throw new MojoExecutionException(message, e);
        }
        headerAndReadmeFiles.add(readmeFile);
        //
        // signature-validator.sh file copy
        //
        headerAndReadmeFiles.addAll(copyHeaderAndReadmeToSubdirectories(headerFile, readmeFile));
        return headerAndReadmeFiles;
    }

    /**
     * Copies <code>README.html</code> and <code>HEADER.html</code> to the source and binaries
     * directories.
     *
     * @param headerFile The originally created <code>HEADER.html</code> file.
     * @param readmeFile The originally created <code>README.html</code> file.
     * @return a {@link List} of created files.
     * @throws MojoExecutionException if the {@link SharedFunctions#copyFile(Log, File, File)}
     *                                fails.
     */
    private List<File> copyHeaderAndReadmeToSubdirectories(final File headerFile, final File readmeFile)
            throws MojoExecutionException {
        final List<File> symbolicLinkFiles = new ArrayList<>();
        final File sourceRoot = new File(distRcVersionDirectory, "source");
        final File binariesRoot = new File(distRcVersionDirectory, "binaries");
        final File sourceHeaderFile = new File(sourceRoot, HEADER_FILE_NAME);
        final File sourceReadmeFile = new File(sourceRoot, README_FILE_NAME);
        final File binariesHeaderFile = new File(binariesRoot, HEADER_FILE_NAME);
        final File binariesReadmeFile = new File(binariesRoot, README_FILE_NAME);
        SharedFunctions.copyFile(getLog(), headerFile, sourceHeaderFile);
        symbolicLinkFiles.add(sourceHeaderFile);
        SharedFunctions.copyFile(getLog(), readmeFile, sourceReadmeFile);
        symbolicLinkFiles.add(sourceReadmeFile);
        SharedFunctions.copyFile(getLog(), headerFile, binariesHeaderFile);
        symbolicLinkFiles.add(binariesHeaderFile);
        SharedFunctions.copyFile(getLog(), readmeFile, binariesReadmeFile);
        symbolicLinkFiles.add(binariesReadmeFile);
        return symbolicLinkFiles;
    }

    /**
     * This method is the setter for the {@link CommonsDistributionStagingMojo#baseDir} field, specifically
     * for the usage in the unit tests.
     *
     * @param baseDir is the {@link File} to be used as the project's root directory when this mojo
     *                is invoked.
     */
    protected void setBaseDir(final File baseDir) {
        this.baseDir = baseDir;
    }
}
