/* ==========================================================================
 * Copyright 2003-2004 Mevenide Team
 *
 * 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.codehaus.mojo.nbm;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.DefaultArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.resolver.ArtifactResolver;
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.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.FileSet;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.archiver.gzip.GZipArchiver;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import org.netbeans.nbbuild.MakeUpdateDesc;

/**
 * Create the NetBeans auto update site definition.
 * @author <a href="mailto:mkleint@codehaus.org">Milos Kleint</a>
 *
 */
@Mojo(name="autoupdate", 
        defaultPhase= LifecyclePhase.PACKAGE, 
        aggregator=true, 
        requiresDependencyResolution= ResolutionScope.RUNTIME )
public class CreateUpdateSiteMojo
        extends AbstractNbmMojo
        implements Contextualizable
{

    /**
     * output directory.
     */
    @Parameter(required=true, defaultValue="${project.build.directory}")
    protected File outputDirectory;
    /**
     * autoupdate site xml file name.
     */
    @Parameter( defaultValue="updates.xml", property="maven.nbm.updatesitexml")
    protected String fileName;
    /**
     * A custom distribution base for the nbms in the update site.
     * If NOT defined, the update site will use a simple relative URL, which is generally what you want.
     * Defining it as "auto" will pick up the distribution URL from each NBM, which is generally wrong. 
     * See <code>distributionUrl</code> in nbm mojo for what url will be used in that case.
     * <p/>
     * The value is either a direct http protocol based URL that points to
     * the location under which all nbm files are located, or
     * <p/>
     * allows to create an update site based on maven repository content.
     * The resulting autoupdate site document can be uploaded as tar.gz to repository as well
     * as attached artifact to the 'nbm-application' project.
     * <br/>
     * Format: id::layout::url same as in maven-deploy-plugin
     * <br/>
     * with the 'default' and 'legacy' layouts. (maven2 vs maven1 layout)
     * <br/>
     * If the value doesn't contain :: characters,
     * it's assumed to be the flat structure and the value is just the URL.
     * 
     * @since 3.0 it's also possible to add remote repository as base
     */
    @Parameter(defaultValue=".", property="maven.nbm.customDistBase")
    private String distBase;

    /**
     * The Maven Project.
     *
     */
    @Parameter(required=true, readonly=true, property="project")
    private MavenProject project;

    /**
     * If the executed project is a reactor project, this will contains the full list of projects in the reactor.
     */
    @Parameter(required=true, readonly=true, defaultValue="${reactorProjects}")
    private List reactorProjects;
    
    /**
     * List of Ant style patterns on artifact GA (groupID:artifactID) that should be included in the update site.
     * Eg. org.netbeans.* matches all artifacts with any groupID starting with 'org.netbeans.',
     * org.*:api will match any artifact with artifactId of 'api' and groupId starting with 'org.'
     * @since 3.14
     */
    @Parameter
    private List<String> updateSiteIncludes;
    

    // <editor-fold defaultstate="collapsed" desc="Component parameters">

    @Component
    private ArtifactFactory artifactFactory;
    /**
     * Contextualized.
     */
    private PlexusContainer container;
    /**
     * Used for attaching the artifact in the project
     *
     */
    @Component
    private MavenProjectHelper projectHelper;

    @Component
    private ArtifactResolver artifactResolver;

    /**
     * Local maven repository.
     *
     */
    @Parameter(readonly=true, required=true, defaultValue="${localRepository}")
    protected ArtifactRepository localRepository;

    // </editor-fold>

    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        Project antProject = registerNbmAntTasks();
        File nbmBuildDirFile = new File( outputDirectory, "netbeans_site" );
        if ( !nbmBuildDirFile.exists() )
        {
            nbmBuildDirFile.mkdirs();
        }

        boolean isRepository = false;
        if ( "auto".equals( distBase ) )
        {
            distBase = null;
        }
        ArtifactRepository distRepository = getDeploymentRepository( distBase, container, getLog() );
        String oldDistBase = null;
        if ( distRepository != null )
        {
            isRepository = true;
        }
        else
        {
            if ( distBase != null && !distBase.contains( "::" ) )
            {
                oldDistBase = distBase;
            }
        }

        if ( "nbm-application".equals( project.getPackaging() ) )
        {
            @SuppressWarnings( "unchecked" )
            Set<Artifact> artifacts = project.getArtifacts();
            for ( Artifact art : artifacts )
            {
                if (!matchesIncludes(art)) {
                    continue;
                }
                ArtifactResult res =
                    turnJarToNbmFile( art, artifactFactory, artifactResolver, project, localRepository );
                if ( res.hasConvertedArtifact() )
                {
                    art = res.getConvertedArtifact();
                }

                if ( art.getType().equals( "nbm-file" ) )
                {
                    Copy copyTask = (Copy) antProject.createTask( "copy" );
                    copyTask.setOverwrite( true );
                    copyTask.setFile( art.getFile() );
                    if ( !isRepository )
                    {
                        copyTask.setFlatten( true );
                        copyTask.setTodir( nbmBuildDirFile );
                    }
                    else
                    {
                        String path = distRepository.pathOf( art );
                        File f = new File( nbmBuildDirFile, path.replace( '/', File.separatorChar ) );
                        copyTask.setTofile( f );
                    }
                    try
                    {
                        copyTask.execute();
                    }
                    catch ( BuildException ex )
                    {
                        throw new MojoExecutionException( "Cannot merge nbm files into autoupdate site", ex );
                    }

                }
                if ( res.isOSGiBundle() )
                {
                    // TODO check for bundles
                }
            }
            getLog().info( "Created NetBeans module cluster(s) at " + nbmBuildDirFile.getAbsoluteFile() );

        }
        else if ( reactorProjects != null && reactorProjects.size() > 0 )
        {

            Iterator it = reactorProjects.iterator();
            while ( it.hasNext() )
            {
                MavenProject proj = (MavenProject) it.next();
                //TODO how to figure where the the buildDir/nbm directory is
                File moduleDir = proj.getFile().getParentFile();
                if ( moduleDir != null && moduleDir.exists() )
                {
                    Copy copyTask = (Copy) antProject.createTask( "copy" );
                    if ( !isRepository )
                    {
                        FileSet fs = new FileSet();
                        File projOutputDirectory = new File( proj.getBuild().getDirectory() );
                        fs.setDir( projOutputDirectory );
                        fs.createInclude().setName( "*.nbm" );
                        copyTask.addFileset( fs );
                        copyTask.setOverwrite( true );
                        copyTask.setFlatten( true );
                        copyTask.setTodir( nbmBuildDirFile );
                    }
                    else
                    {
                        File target = new File( proj.getBuild().getDirectory() );
                        boolean has = false;
                        File[] fls = target.listFiles();
                        if ( fls != null )
                        {
                            for ( File fl : fls )
                            {
                                if ( fl.getName().endsWith( ".nbm" ) )
                                {
                                    copyTask.setFile( fl );
                                    has = true;
                                    break;
                                }
                            }
                        }
                        if ( !has )
                        {
                            continue;
                        }
                        Artifact art =
                            artifactFactory.createArtifact( proj.getGroupId(), proj.getArtifactId(), proj.getVersion(),
                                                            null, "nbm-file" );
                        String path = distRepository.pathOf( art );
                        File f = new File( nbmBuildDirFile, path.replace( '/', File.separatorChar ) );
                        copyTask.setTofile( f );
                    }
                    try
                    {
                        copyTask.execute();
                    }
                    catch ( BuildException ex )
                    {
                        throw new MojoExecutionException( "Cannot merge nbm files into autoupdate site", ex );
                    }
                }
            }
        }
        else
        {
            throw new MojoExecutionException(
                    "This goal only makes sense on reactor projects or project with 'nbm-application' packaging." );

        }
        MakeUpdateDesc descTask = (MakeUpdateDesc) antProject.createTask( "updatedist" );
        File xmlFile = new File( nbmBuildDirFile, fileName );
        descTask.setDesc( xmlFile );
        if ( oldDistBase != null )
        {
            descTask.setDistBase( oldDistBase );
        }
        if ( distRepository != null )
        {
            descTask.setDistBase( distRepository.getUrl() );
        }
        FileSet fs = new FileSet();
        fs.setDir( nbmBuildDirFile );
        fs.createInclude().setName( "**/*.nbm" );
        descTask.addFileset( fs );
        try
        {
            descTask.execute();
        }
        catch ( BuildException ex )
        {
            throw new MojoExecutionException( "Cannot create autoupdate site xml file", ex );
        }
        getLog().info( "Generated autoupdate site content at " + nbmBuildDirFile.getAbsolutePath() );

        try
        {
            GZipArchiver gz = new GZipArchiver();
            gz.addFile( xmlFile, fileName );
            File gzipped = new File( nbmBuildDirFile, fileName + ".gz" );
            gz.setDestFile( gzipped );
            gz.createArchive();
            if ( "nbm-application".equals( project.getPackaging() ) )
            {
                projectHelper.attachArtifact( project, "xml.gz", "updatesite", gzipped );
            }
        }
        catch ( Exception ex )
        {
            throw new MojoExecutionException( "Cannot create gzipped version of the update site xml file.", ex );
        }

    }

    private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+)::(.+)::(.+)" );

    static ArtifactRepository getDeploymentRepository( String distBase, PlexusContainer container, Log log )
        throws MojoExecutionException, MojoFailureException
    {

        ArtifactRepository repo = null;

        if ( distBase != null )
        {

            Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher( distBase );

            if ( !matcher.matches() )
            {
                if ( !distBase.contains( "::" ) )
                {
                    //backward compatibility gag.
                    return null;
                }
                throw new MojoFailureException( distBase,
                        "Invalid syntax for repository.",
                        "Invalid syntax for alternative repository. Use \"id::layout::url\"." );
            }
            else
            {
                String id = matcher.group( 1 ).trim();
                String layout = matcher.group( 2 ).trim();
                String url = matcher.group( 3 ).trim();

                ArtifactRepositoryLayout repoLayout;
                try
                {
                    repoLayout = (ArtifactRepositoryLayout) container.lookup( ArtifactRepositoryLayout.ROLE, layout );
                }
                catch ( ComponentLookupException e )
                {
                    throw new MojoExecutionException( "Cannot find repository layout: " + layout, e );
                }

                repo = new DefaultArtifactRepository( id, url, repoLayout );
            }
        }
        return repo;
    }

    public void contextualize( Context context )
        throws ContextException
    {
        this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
    }

    private boolean matchesIncludes( Artifact art )
    {
        if (updateSiteIncludes != null) {
            String s = art.getGroupId() + ":" + art.getArtifactId();
            for (String p : updateSiteIncludes) {
                //TODO optimize and only do once per execution.
                p = p.replace(".", "\\.").replace( "*", ".*");
                Pattern patt = Pattern.compile( p );
                if (patt.matcher( s).matches()) {
                    return true;
                }
            }
            return false;    
        }
        return true;
    }
}
