/* ==========================================================================
 * 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.netbeans.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;
    }
}
