package org.apache.maven.plugin.patch;

/*
 * 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.
 */

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;
import org.codehaus.plexus.util.cli.StreamConsumer;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Apply one or more patches to project sources.
 */
@Mojo( name = "apply", defaultPhase = LifecyclePhase.PROCESS_SOURCES )
public class ApplyMojo
    extends AbstractMojo
{

    public static final List PATCH_FAILURE_WATCH_PHRASES;

    public static final List DEFAULT_IGNORED_PATCHES;

    public static final List DEFAULT_IGNORED_PATCH_PATTERNS;

    static
    {
        List watches = new ArrayList();

        watches.add( "fail" );
        watches.add( "skip" );
        watches.add( "reject" );

        PATCH_FAILURE_WATCH_PHRASES = watches;

        List ignored = new ArrayList();

        ignored.add( ".svn" );
        ignored.add( "CVS" );

        DEFAULT_IGNORED_PATCHES = ignored;

        List ignoredPatterns = new ArrayList();

        ignoredPatterns.add( ".svn/**" );
        ignoredPatterns.add( "CVS/**" );

        DEFAULT_IGNORED_PATCH_PATTERNS = ignoredPatterns;
    }

    /**
     * Whether to exclude default ignored patch items, such as <code>.svn</code> or <code>CVS</code> directories.
     */
    @Parameter( defaultValue = "true" )
    private boolean useDefaultIgnores;

    /**
     * The list of patch file names, supplying the order in which patches should be applied. The path names in this list
     * must be relative to the base directory specified by the parameter <code>patchDirectory</code>. This parameter
     * is mutually exclusive with the <code>patchfile</code> parameter.
     */
    @Parameter
    protected List patches;

    /**
     * Whether to skip this goal's execution.
     */
    @Parameter( alias = "patch.apply.skip", defaultValue = "false" )
    private boolean skipApplication;

    /**
     * Flag to enable/disable optimization file from being written. This file tracks the patches that were applied the
     * last time this goal actually executed. It is required for cases where project-sources optimizations are enabled,
     * since project-sources will not be re-unpacked if they are at least as fresh as the source archive. If we avoid
     * re-unpacking project sources, we need to make sure we don't reapply patches.<br/> <strong>Note:</strong> If the
     * list of patches changes and this flag is enabled, a "<code>mvn clean</code>" must be executed before the next
     * build, to remove the tracking file.
     */
    @Parameter( defaultValue = "true" )
    private boolean optimizations;

    /**
     * This is the tracking file used to maintain a list of the patches applied to the unpacked project sources which
     * are currently in the target directory. If this file is present, and project-source unpacking is optimized
     * (meaning it won't re-unpack unless the project-sources archive is newer), this goal will not execute and no
     * patches will be applied in the current build.
     */
    @Parameter( defaultValue = "${project.build.directory}/optimization-files/patches-applied.txt" )
    private File patchTrackingFile;

    /**
     * The target directory for applying patches. Files in this directory will be modified.
     */
    @Parameter( alias = "patchTargetDir", defaultValue = "${project.build.sourceDirectory}" )
    private File targetDirectory;

    /**
     * Flag being <code>true</code> if the desired behavior is to fail the build on the first failed patch detected.
     */
    @Parameter( defaultValue = "true" )
    private boolean failFast;

    /**
     * Setting natural order processing to <code>true</code> will cause all patches in a directory to be processed in
     * a natural order alleviating the need to declare patches directly in the project file.
     */
    @Parameter( defaultValue = "false" )
    private boolean naturalOrderProcessing;

    /**
     * When the <code>strictPatching</code> flag is set, this parameter is useful to mark certain contents of the
     * patch-source directory that should be ignored without causing the build to fail.
     */
    @Parameter
    private List ignoredPatches;

    /**
     * Flag that, when set to <code>true</code>, will make sure that all patches included in the <code>patches</code>
     * list must be present and describe the full contents of the patch directory. If <code>strictPatching</code> is
     * set to <code>true</code>, and the <code>patches</code> list has a value that does not correspond to a file
     * in the patch directory, the build will fail. If <code>strictPatching</code> is set to <code>true</code>, and
     * the patch directory contains files not listed in the <code>patches</code> parameter, the build will fail. If
     * set to <code>false</code>, only the patches listed in the <code>patches</code> parameter that have
     * corresponding files will be applied; the rest will be ignored.
     */
    @Parameter( defaultValue = "false" )
    private boolean strictPatching;

    /**
     * The number of directories to be stripped from patch file paths, before applying, starting from the leftmost, or
     * root-est.
     */
    @Parameter( defaultValue = "0" )
    private int strip;

    /**
     * Whether to ignore whitespaces when applying the patches.
     */
    @Parameter( defaultValue = "true" )
    private boolean ignoreWhitespace;

    /**
     * Whether to treat these patches as having reversed source and dest in the patch syntax.
     */
    @Parameter( defaultValue = "false" )
    private boolean reverse;

    /**
     * Whether to make backups of the original files before modding them.
     */
    @Parameter( defaultValue = "false" )
    private boolean backups;

    /**
     * List of phrases to watch for in the command output from the patch tool. If one is found, it will cause the build
     * to fail. All phrases should be lower-case <em>only</em>. By default, the phrases <code>fail</code>,
     * <code>skip</code> and <code>reject</code> are used.
     */
    @Parameter
    private List failurePhrases = PATCH_FAILURE_WATCH_PHRASES;

    /**
     * The original file which will be modified by the patch. By default, the patch tool will automatically derive the
     * original file from the header of the patch file.
     */
    @Parameter
    private File originalFile;

    /**
     * The output file which is the original file, plus modifications from the patch. By default, the file(s) will be
     * patched inplace.
     */
    @Parameter
    private File destFile;

    /**
     * The single patch file to apply. This parameter is mutually exclusive with the <code>patches</code> parameter.
     */
    @Parameter
    private File patchFile;

    /**
     * The base directory for the file names specified by the parameter <code>patches</code>.
     */
    @Parameter( defaultValue = "src/main/patches" )
    private File patchDirectory;

    /**
     * When set to <code>true</code>, the empty files resulting from the patching process are removed. Empty ancestor
     * directories are removed as well.
     *
     * @since 1.1
     */
    @Parameter( defaultValue = "false" )
    private boolean removeEmptyFiles;

    /**
     * apply --binary option to patch command line
     * @since 1.2
     */
    @Parameter( defaultValue = "false" )
    private boolean binary;

    /**
     * Apply the patches. Give preference to patchFile over patchSourceDir/patches, and preference to originalFile over
     * workDir.
     */
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        boolean patchDirEnabled = ( ( patches != null ) && !patches.isEmpty() ) || naturalOrderProcessing;
        boolean patchFileEnabled = patchFile != null;

        // if patches is null or empty, and naturalOrderProcessing is not true then disable patching
        if ( !patchFileEnabled && !patchDirEnabled )
        {
            getLog().info( "Patching is disabled for this project." );
            return;
        }

        if ( skipApplication )
        {
            getLog().info( "Skipping patch file application (per configuration)." );
            return;
        }

        patchTrackingFile.getParentFile().mkdirs();

        Map patchesToApply;

        try
        {
            if ( patchFileEnabled )
            {
                patchesToApply = Collections.singletonMap( patchFile.getName(), createPatchCommand( patchFile ) );
            }
            else
            {
                if ( !patchDirectory.isDirectory() )
                {
                    throw new FileNotFoundException( "The base directory for patch files does not exist: "
                        + patchDirectory );
                }

                List foundPatchFiles = FileUtils.getFileNames( patchDirectory, "*", null, false );

                patchesToApply = findPatchesToApply( foundPatchFiles, patchDirectory );

                checkStrictPatchCompliance( foundPatchFiles );
            }

            String output = applyPatches( patchesToApply );

            checkForWatchPhrases( output );

            writeTrackingFile( patchesToApply );
        }
        catch ( IOException ioe )
        {
            throw new MojoExecutionException( "Unable to obtain list of patch files", ioe );
        }
    }

    private Map findPatchesToApply( List foundPatchFiles, File patchSourceDir )
        throws MojoFailureException
    {
        Map patchesApplied = new LinkedHashMap();

        if ( naturalOrderProcessing )
        {
            patches = new ArrayList( foundPatchFiles );
            Collections.sort( patches );
        }

        String alreadyAppliedPatches = "";

        try
        {
            if ( optimizations && patchTrackingFile.exists() )
            {
                alreadyAppliedPatches = FileUtils.fileRead( patchTrackingFile );
            }
        }
        catch ( IOException ioe )
        {
            throw new MojoFailureException( "unable to read patch tracking file: " + ioe.getMessage() );
        }

        for (Object patche : patches) {
            String patch = (String) patche;

            if (!alreadyAppliedPatches.contains(patch)) {
                File patchFile = new File(patchSourceDir, patch);

                getLog().debug("Looking for patch: " + patch + " in: " + patchFile);

                if (!patchFile.exists()) {
                    if (strictPatching) {
                        throw new MojoFailureException(this, "Patch operation cannot proceed.",
                                "Cannot find specified patch: \'" + patch
                                        + "\' in patch-source directory: \'" + patchSourceDir
                                        + "\'.\n\nEither fix this error, "
                                        + "or relax strictPatching.");
                    } else {
                        getLog().info(
                                "Skipping patch: " + patch + " listed in the parameter \"patches\"; "
                                        + "it is missing.");
                    }
                } else {
                    foundPatchFiles.remove(patch);

                    patchesApplied.put(patch, createPatchCommand(patchFile));
                }
            }
        }

        return patchesApplied;
    }

    private void checkStrictPatchCompliance( List foundPatchFiles )
        throws MojoExecutionException
    {
        if ( strictPatching )
        {
            List ignored = new ArrayList();

            if ( ignoredPatches != null )
            {
                ignored.addAll( ignoredPatches );
            }

            if ( useDefaultIgnores )
            {
                ignored.addAll( DEFAULT_IGNORED_PATCHES );
            }

            List limbo = new ArrayList( foundPatchFiles );

            for (Object anIgnored : ignored) {
                String ignoredFile = (String) anIgnored;

                limbo.remove(ignoredFile);
            }

            if ( !limbo.isEmpty() )
            {
                StringBuilder extraFileBuffer = new StringBuilder();

                extraFileBuffer.append("Found ").append(limbo.size()).append(" unlisted patch files:");

                for (Object foundPatchFile : foundPatchFiles) {
                    String patch = (String) foundPatchFile;

                    extraFileBuffer.append("\n  \'").append(patch).append('\'');
                }

                extraFileBuffer.append( "\n\nEither remove these files, "
                    + "add them to the patches configuration list, " + "or relax strictPatching." );

                throw new MojoExecutionException( extraFileBuffer.toString() );
            }
        }
    }

    private String applyPatches( Map patchesApplied )
        throws MojoExecutionException
    {
        final StringWriter outputWriter = new StringWriter();

        StreamConsumer consumer = new StreamConsumer()
        {
            public void consumeLine( String line )
            {
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( line );
                }

                outputWriter.write( line + "\n" );
            }
        };

        // used if failFast is false
        List failedPatches = new ArrayList();

        for (Object o : patchesApplied.entrySet()) {
            Entry entry = (Entry) o;
            String patchName = (String) entry.getKey();
            Commandline cli = (Commandline) entry.getValue();

            try {
                getLog().info("Applying patch: " + patchName);

                int result = executeCommandLine(cli, consumer, consumer);

                if (result != 0) {
                    if (failFast) {
                        throw new MojoExecutionException("Patch command failed with exit code " + result + " for "
                                + patchName + ". Please see console and debug output for more information.");
                    } else {
                        failedPatches.add(patchName);
                    }
                }
            } catch (CommandLineException e) {
                throw new MojoExecutionException("Failed to apply patch: " + patchName
                        + ". See debug output for more information.", e);
            }
        }

        if ( !failedPatches.isEmpty() )
        {
            getLog().error( "Failed applying one or more patches:" );
            for (Object failedPatche : failedPatches) {
                getLog().error("* " + failedPatche);
            }
            throw new MojoExecutionException( "Patch command failed for one or more patches."
                + " Please see console and debug output for more information." );
        }

        return outputWriter.toString();
    }

    private int executeCommandLine( Commandline cli, StreamConsumer out, StreamConsumer err )
        throws CommandLineException
    {
        if ( getLog().isDebugEnabled() )
        {
            getLog().debug( "Executing: " + cli );
        }

        int result = CommandLineUtils.executeCommandLine( cli, out, err );

        if ( getLog().isDebugEnabled() )
        {
            getLog().debug( "Exit code: " + result );
        }

        return result;
    }

    private void writeTrackingFile( Map patchesApplied )
        throws MojoExecutionException
    {
        FileWriter writer = null;
        try
        {
            boolean appending = patchTrackingFile.exists();

            writer = new FileWriter( patchTrackingFile, appending );

            for ( Iterator it = patchesApplied.keySet().iterator(); it.hasNext(); )
            {
                if ( appending )
                {
                    writer.write( System.getProperty( "line.separator" ) );
                }

                String patch = (String) it.next();
                writer.write( patch );

                if ( it.hasNext() )
                {
                    writer.write( System.getProperty( "line.separator" ) );
                }
            }

            writer.flush();
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Failed to write patch-tracking file: " + patchTrackingFile, e );
        }
        finally
        {
            IOUtil.close( writer );
        }
    }

    private void checkForWatchPhrases( String output )
        throws MojoExecutionException
    {
        for (Object failurePhrase : failurePhrases) {
            String phrase = (String) failurePhrase;

            if (output.contains(phrase)) {
                throw new MojoExecutionException("Failed to apply patches (detected watch-phrase: \'" + phrase
                        + "\' in output). " + "If this is in error, configure the patchFailureWatchPhrases parameter.");
            }
        }
    }

    /**
     * Add a new Patch task to the Ant calling mechanism. Give preference to originalFile/destFile, then workDir, and
     * finally ${basedir}.
     */
    private Commandline createPatchCommand( File patchFile )
    {
        Commandline cli = new Commandline();

        cli.setExecutable( "patch" );

        cli.setWorkingDirectory( targetDirectory.getAbsolutePath() );

        cli.createArg().setValue( "-p" + strip );

        if ( binary )
        {
            cli.createArg().setValue( "--binary" );
        }

        if ( ignoreWhitespace )
        {
            cli.createArg().setValue( "-l" );
        }

        if ( reverse )
        {
            cli.createArg().setValue( "-R" );
        }

        if ( backups )
        {
            cli.createArg().setValue( "-b" );
        }

        if ( removeEmptyFiles )
        {
            cli.createArg().setValue( "-E" );
        }

        cli.createArg().setValue( "-i" );
        cli.createArg().setFile( patchFile );

        if ( destFile != null )
        {
            cli.createArg().setValue( "-o" );
            cli.createArg().setFile( destFile );
        }

        if ( originalFile != null )
        {
            cli.createArg().setFile( originalFile );
        }

        return cli;
    }

}
