/* ==========================================================================
 * Copyright 2003-2006 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.repository;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.deployer.ArtifactDeployer;
import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.installer.ArtifactInstallationException;
import org.apache.maven.artifact.installer.ArtifactInstaller;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.artifact.AttachedArtifact;
import org.apache.maven.project.artifact.ProjectArtifactMetadata;
import org.netbeans.nbm.utils.AbstractNetbeansMojo;
import org.netbeans.nbm.utils.ExamineManifest;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Input;
import org.apache.tools.ant.taskdefs.PathConvert;
import org.apache.tools.ant.types.FileSet;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;

/**
 * A goal for identifying NetBeans modules from the installation and populating the local
 * repository with them. Optionally you can also deploy to a remote repository.
 * <p>
 * If you are looking for an existing remote repository for NetBeans artifacts, check out
 * <a href="http://bits.netbeans.org/nexus/content/groups/netbeans/">http://bits.netbeans.org/nexus/content/groups/netbeans/</a>,
 * it contains API artifacts for multiple releases.
 * <a href="http://bits.netbeans.org/netbeans/trunk/maven-snapshot/">http://bits.netbeans.org/netbeans/trunk/maven-snapshot/</a>
 * may also be used for <code>SNAPSHOT</code> artifacts if you wish to test development builds.
 * </p><p>
 * See this <a href="http://mojo.codehaus.org/nbm-maven/nbm-maven-plugin/repository.html">HOWTO</a> on how to generate the NetBeans binaries required
 * by this goal.
 * </p>
 *
 * @author <a href="mailto:mkleint@codehaus.org">Milos Kleint</a>
 */
@Mojo(name="populate", aggregator=true, requiresProject=false)
public class PopulateRepositoryMojo
    extends AbstractNetbeansMojo
{
    private static final String GROUP_API = ".api";
    private static final String GROUP_IMPL = ".modules";
    private static final String GROUP_EXTERNAL = ".external";
    private static final String GROUP_CLUSTER = ".cluster";

    
    /**
     * a prefix for groupId of generated content, 
     * eg. for org.netbeans value will generate org.netbeans.cluster groupId for clusters and org.netbeans.modules for module artifacts.
     * @since 1.2
     */
    @Parameter(property="groupIdPrefix", defaultValue = "org.netbeans")
    private String groupIdPrefix;
    
    /**
     * an url where to deploy the NetBeans artifacts. Optional, if not specified, the artifacts will be only installed
     * in local repository, if you need to give credentials to access remote repo, the id of the server is hardwired to "netbeans".
     */
    @Parameter(property="deployUrl")
    private String deployUrl;

    /**
     * By default the generated metadata is installed in local repository.
     * Setting this parameter to false will avoid installing the bits. Only meaningful together with
     * a defined "deployUrl" parameter.
     * @since 3.0
     */
    @Parameter(defaultValue="false", property="skipInstall")
    private boolean skipLocalInstall;


    /**
     * Location of NetBeans installation
     */
    @Parameter(property="netbeansInstallDirectory", required=true)
    protected File netbeansInstallDirectory;

    /**
     * If you want to install/deploy also NetBeans api javadocs, download the javadoc zip file from netbeans.org
     * expand it to a directory, it should contain multiple zip files. Define this parameter as absolute path to the zip files folder.
     *
     */
    @Parameter(property="netbeansJavadocDirectory")
    protected File netbeansJavadocDirectory;

    /**
     * Assumes a folder with &lt;code-name-base&gt;.zip files containing sources for modules.
     */
    @Parameter(property="netbeansSourcesDirectory")
    protected File netbeansSourcesDirectory;

    /**
     * If defined, will match the nbm files found in the designated folder with the modules
     * and upload the nbm file next to the module jar in local and remote repositories.
     *
     * Assumes a folder with &lt;code-name-base&gt;.nbm files containing nbm files for modules.
     * @since 3.0
     */
    @Parameter(property="netbeansNbmDirectory", required=true)
    protected File netbeansNbmDirectory;

    /**
     * When specified, will force all modules to have the designated version.
     * Good when depending on releases. Then you would for example specify RELEASE50 in this parameter and
     * all modules get this version in the repository. If not defined, the maven version is
     * derived from the OpenIDE-Module-Specification-Version manifest attribute.
     * <p>
     * Highly Recommended!
     * </p>
     */
    @Parameter(property="forcedVersion")
    protected String forcedVersion;

    /**
     * When specified it points to a directory containing a Maven Indexer
     * (Nexus) Lucene index. This index will be used to find external libraries that
     * are referenced by NetBeans modules and populate the POM metadata with correct
     * dependencies. Any dependencies not found this way, will be generated with a unique
     * id under the org.netbeans.external groupId.
     * <p/>
     * Use the {@code download} goal to retrieve the index.
     * @since 3.0
     */
    @Parameter(property="nexusIndexDirectory")
    private File nexusIndexDirectory;

    /**
     * Whether to create cluster POMs in the {@code org.netbeans.cluster} group.
     * Only meaningful when {@code forcedVersion} is defined.
     * @since 3.7
     */
    @Parameter(defaultValue="true", property="defineCluster")   
    private boolean defineCluster;

    /**
     * Optional remote repository to use for inspecting remote dependencies.
     * This may be used to populate just part of an installation,
     * when base modules are already available in Maven format.
     * Currently only supported when {@code forcedVersion} is defined.
     * @since 3.7
     */
    @Parameter(property="dependencyRepositoryUrl")
    private String dependencyRepositoryUrl;

    /**
     * Repository ID to use when inspecting remote dependencies.
     * Only meaningful when {@code dependencyRepositoryUrl} is defined.
     * @since 3.7
     */
    @Parameter(defaultValue="temp", property="dependencyRepositoryId")
    private String dependencyRepositoryId;

    /**
     * Colon separated artefact coordinate groupId:artefactId:version that
     * represent parent to be used
     *
     * @since 1.4
     */
    @Parameter(property = "parentGAV", required = false)
    private String parentGAV;
    
    // <editor-fold defaultstate="collapsed" desc="Component parameters">
    /**
     * Local maven repository.
     */
    @Parameter(required=true, readonly=true, defaultValue="${localRepository}")
    protected ArtifactRepository localRepository;

    /**
     * Maven ArtifactFactory.
     */
    @Component
    private ArtifactFactory artifactFactory;

    /**
     * Maven ArtifactInstaller.
     */
    @Component
    private ArtifactInstaller artifactInstaller;

    /**
     * Maven ArtifactDeployer.
     *
     */
    @Component
    private ArtifactDeployer artifactDeployer;

    /**
     * Maven ArtifactHandlerManager
     *
     */
    @Component
    private ArtifactHandlerManager artifactHandlerManager;

    /**
     * Maven ArtifactRepositoryFactory.
     *
     */
    @Component
    private ArtifactRepositoryFactory repositoryFactory;

    @Component
    private ArtifactResolver artifactResolver;

    @Component
    private ArtifactRepositoryLayout artifactRepositoryLayout;
// </editor-fold>

    // parent handler in case we have one
    private Parent artefactParent = null;
    
    @Override
    public void execute()
        throws MojoExecutionException
    {
        getLog().info( "Populate repository with NetBeans modules" );
        Project antProject = antProject();
        ArtifactRepository deploymentRepository = null;
        
        if (parentGAV != null) 
        {
            // populate artefactParent
            artefactParent = new Parent();
            String[] split = parentGAV.split(":");
            if (split.length != 3) {
                throw new MojoExecutionException(
                    "parentGAV should respect the following format groupId:artefactId:version" );
            }
            artefactParent.setArtifactId( split[0] );
            artefactParent.setArtifactId( split[1] );
            artefactParent.setVersion( split[2] );
        }
        
        if ( deployUrl != null )
        {
            ArtifactRepositoryLayout layout = new DefaultRepositoryLayout();
            deploymentRepository = repositoryFactory.createDeploymentArtifactRepository(
                "netbeans", deployUrl, layout, true );
        }
        else if ( skipLocalInstall )
        {
            throw new MojoExecutionException(
                    "When skipping install to local repository, one shall define the deployUrl parameter" );
        }

        IndexSearcher searcher = null;
        if ( nexusIndexDirectory != null && nexusIndexDirectory.exists() )
        {
            try
            {
                Directory nexusDir = FSDirectory.open( nexusIndexDirectory.toPath() );
                IndexReader nexusReader = DirectoryReader.open( nexusDir );
                searcher = new IndexSearcher( nexusReader );
                getLog().info( "Opened index with " + nexusReader.numDocs() + " documents" );
            }
            catch ( IOException ex )
            {
                getLog().error( "Could not open " + nexusIndexDirectory, ex );
            }
        }

        if ( netbeansInstallDirectory == null )
        {
            Input input = (Input) antProject.createTask( "input" );
            input.setMessage( "Please enter NetBeans installation directory:" );
            input.setAddproperty( "installDir" );
            try
            {
                input.execute();
            }
            catch ( BuildException e )
            {
                getLog().error( "Cannot run ant:input" );
                throw new MojoExecutionException( e.getMessage(), e );
            }
            String prop = antProject.getProperty( "installDir" );
            netbeansInstallDirectory = new File( prop );
        }

        File rootDir = netbeansInstallDirectory;
        if ( !rootDir.exists() )
        {
            getLog().error( "NetBeans installation doesn't exist." );
            throw new MojoExecutionException( "NetBeans installation doesn't exist." );
        }
        getLog().info( "Copying NetBeans artifacts from " + netbeansInstallDirectory );

        PathConvert convert = (PathConvert) antProject.createTask( "pathconvert" );
        convert.setPathSep( "," );
        convert.setProperty( "netbeansincludes" );
        FileSet set = new FileSet();
        set.setDir( rootDir );
        set.createInclude().setName( "**/modules/*.jar" );
        set.createInclude().setName( "*/core/*.jar" );
        set.createInclude().setName( "platform*/lib/*.jar" );

        convert.createPath().addFileset( set );
        try
        {
            convert.execute();
        }
        catch ( BuildException e )
        {
            getLog().error( "Cannot run ant:pathconvert" );
            throw new MojoExecutionException( e.getMessage(), e );
        }

        String prop = antProject.getProperty( "netbeansincludes" );
        StringTokenizer tok = new StringTokenizer( prop, "," );
        HashMap<ModuleWrapper, Artifact> moduleDefinitions = new HashMap<ModuleWrapper, Artifact>();
        HashMap<String, Collection<ModuleWrapper>> clusters = new HashMap<String, Collection<ModuleWrapper>>();
        while ( tok.hasMoreTokens() )
        {
            String token = tok.nextToken();
            File module = new File( token );
            String clust = module.getAbsolutePath().substring( rootDir.getAbsolutePath().length() + 1 );
            clust = clust.substring( 0, clust.indexOf( File.separator ) );
            ExamineManifest examinator = new ExamineManifest( getLog() );
            examinator.setPopulateDependencies( true );
            examinator.setJarFile( module );
            examinator.checkFile();
            if ( examinator.isNetBeansModule() || examinator.isOsgiBundle() )
            {
                //TODO get artifact id from the module's manifest?
                String artifact = module.getName().substring( 0, module.getName().indexOf( ".jar" ) );
                if ( "boot".equals( artifact ) )
                {
                    artifact = "org-netbeans-bootstrap";
                }
                if ( "core".equals( artifact ) )
                {
                    artifact = "org-netbeans-core-startup";
                }
                if ( "core-base".equals( artifact ) )
                {
                    artifact = "org-netbeans-core-startup-base";
                }                
                String version = forcedVersion == null ? examinator.getSpecVersion() : forcedVersion;
                String group = groupIdPrefix + (examinator.isOsgiBundle() ? GROUP_EXTERNAL : examinator.hasPublicPackages() ? GROUP_API : GROUP_IMPL);
                Artifact art = createArtifact( artifact, version, group );
                if ( examinator.isOsgiBundle() )
                {
                    Dependency dep = findExternal( searcher, module );
                    if ( dep != null )
                    {
                        // XXX use those coords instead of publishing this
                        // (for now all bundles are from Orbit, which does not publish to Central, or specially built)
                    }
                }
                ModuleWrapper wr = new ModuleWrapper( artifact, version, group, examinator, module );
                wr.setCluster( clust );
                moduleDefinitions.put( wr, art );
                Collection<ModuleWrapper> col = clusters.get( clust );
                if ( col == null )
                {
                    col = new ArrayList<ModuleWrapper>();
                    clusters.put( clust, col );
                }
                col.add( wr );
            }
        }
        List<ModuleWrapper> wrapperList = new ArrayList<ModuleWrapper>( moduleDefinitions.keySet() );
        int count = wrapperList.size() + 1;
        int index = 0;
        File javadocRoot = null;
        if ( netbeansJavadocDirectory != null )
        {
            javadocRoot = netbeansJavadocDirectory ;
            if ( !javadocRoot.exists() )
            {
                javadocRoot = null;
                throw new MojoExecutionException(
                    "The netbeansJavadocDirectory parameter doesn't point to an existing folder" );
            }
        }
        File sourceRoot = null;
        if ( netbeansSourcesDirectory != null )
        {
            sourceRoot = netbeansSourcesDirectory;
            if ( !sourceRoot.exists() )
            {
                sourceRoot = null;
                throw new MojoExecutionException(
                    "The netbeansSourceDirectory parameter doesn't point to an existing folder" );
            }
        }

        File nbmRoot = null;
        if ( netbeansNbmDirectory != null )
        {
            nbmRoot = netbeansNbmDirectory;
            if ( !nbmRoot.exists() )
            {
                nbmRoot = null;
                throw new MojoExecutionException(
                    "The nbmDirectory parameter doesn't point to an existing folder" );
            }
        }

        List<ExternalsWrapper> externals = new ArrayList<ExternalsWrapper>();
        try
        {
            for ( Map.Entry<ModuleWrapper, Artifact> elem : moduleDefinitions.entrySet() )
            {
                ModuleWrapper man = elem.getKey();
                Artifact art = elem.getValue();
                index = index + 1;
                getLog().info( "Processing " + index + "/" + count );
                File pom = createMavenProject( man, wrapperList, externals, searcher );
                ArtifactMetadata metadata = new ProjectArtifactMetadata( art, pom );
                art.addMetadata( metadata );
                File javadoc = null;
                Artifact javadocArt = null;
                if ( javadocRoot != null )
                {
                    File zip = new File( javadocRoot, art.getArtifactId() + ".zip" );
                    if ( zip.exists() )
                    {
                        javadoc = zip;
                        javadocArt = createAttachedArtifact( art, javadoc, "jar", "javadoc" );
                    }
                }
                File source = null;
                Artifact sourceArt = null;
                if ( sourceRoot != null )
                {
                    File zip = new File( sourceRoot, art.getArtifactId() + ".zip" );
                    if ( zip.exists() )
                    {
                        source = zip;
                        sourceArt = createAttachedArtifact( art, source, "jar", "sources" );
                    }
                }
                File nbm = null;
                Artifact nbmArt = null;
                if ( nbmRoot != null )
                {
                    File zip = new File( nbmRoot, art.getArtifactId() + ".nbm" );

                    if ( !zip.exists() )
                    {
                        zip = new File( nbmRoot,
                            man.getCluster() + File.separator + art.getArtifactId() + ".nbm" );
                    }
                    if ( zip.exists() )
                    {
                        nbm = zip;
                        nbmArt = createAttachedArtifact( art, nbm, "nbm-file", null );
                        if ( nbmArt.getArtifactHandler().getExtension().equals( "nbm-file" ) )
                        {
                            // Maven 2.x compatibility.
                            nbmArt = createAttachedArtifact( art, nbm, "nbm", null );
                        }
                        assert nbmArt.getArtifactHandler().getExtension().equals( "nbm" );
                    }
                }
                File moduleJar = man.getFile();
                File moduleJarMinusCP = null;
                if ( ! man.getModuleManifest().getClasspath().isEmpty() )
                {
                    try
                    {
                        moduleJarMinusCP = File.createTempFile( man.getArtifact(), ".jar" );
                        moduleJarMinusCP.deleteOnExit();
                        InputStream is = new FileInputStream( moduleJar );
                        try
                        {
                            OutputStream os = new FileOutputStream( moduleJarMinusCP );
                            try
                            {
                                JarInputStream jis = new JarInputStream( is );
                                Manifest mani = new Manifest( jis.getManifest() );
                                mani.getMainAttributes().remove( Attributes.Name.CLASS_PATH );
                                if ( !man.deps.isEmpty() )
                                { // MNBMODULE-132
                                    StringBuilder b = new StringBuilder();
                                    for ( Dependency dep : man.deps )
                                    {
                                        if ( b.length() > 0 )
                                        {
                                            b.append( ' ' );
                                        }
                                        b.append( dep.getGroupId() ).append( ':' ).append( dep.getArtifactId() ).append( ':' ).append( dep.getVersion() );
                                        if (dep.getClassifier() != null) {
                                            b.append(":").append(dep.getClassifier());
                                        }
                                    }
                                    mani.getMainAttributes().putValue( "Maven-Class-Path", b.toString() );
                                }
                                else
                                {
                                    getLog().warn( "did not find any external artifacts for " + man.getModule() );
                                }
                                JarOutputStream jos = new JarOutputStream( os, mani );
                                JarEntry entry;
                                while ( ( entry = jis.getNextJarEntry() ) != null )
                                {
                                    if ( entry.getName().matches( "META-INF/.+[.]SF" ) )
                                    {
                                        throw new IOException( "cannot handle signed JARs" );
                                    }
                                    jos.putNextEntry( entry );
                                    byte[] buf = new byte[(int) entry.getSize()];
                                    int read = jis.read( buf, 0, buf.length );
                                    if ( read != buf.length )
                                    {
                                        throw new IOException( "read wrong amount" );
                                    }
                                    jos.write( buf );
                                }
                                jos.close();
                            }
                            finally
                            {
                                os.close();
                            }
                        }
                        finally
                        {
                            is.close();
                        }
                    }
                    catch ( IOException x )
                    {
                        getLog().warn( "Could not process " + moduleJar + ": " + x, x );
                        moduleJarMinusCP.delete();
                        moduleJarMinusCP = null;
                    }
                }
                try
                {
                    if ( !skipLocalInstall )
                    {
                        install( moduleJarMinusCP != null ? moduleJarMinusCP : moduleJar, art );
                        if ( javadoc != null )
                        {
                            install( javadoc, javadocArt );
                        }
                        if ( source != null )
                        {
                            install( source, sourceArt );
                        }
                        if ( nbm != null )
                        {
                            install( nbm, nbmArt );
                        }
                    }
                    try
                    {
                        if ( deploymentRepository != null )
                        {
                            artifactDeployer.deploy( moduleJarMinusCP != null ? moduleJarMinusCP : moduleJar, art,
                                                     deploymentRepository, localRepository );
                            if ( javadoc != null )
                            {
                                artifactDeployer.deploy( javadoc, javadocArt, deploymentRepository, localRepository );
                            }
                            if ( source != null )
                            {
                                artifactDeployer.deploy( source, sourceArt, deploymentRepository, localRepository );
                            }
                            if ( nbm != null )
                            {
                                artifactDeployer.deploy( nbm, nbmArt, deploymentRepository, localRepository );
                            }
                        }
                    }
                    catch ( ArtifactDeploymentException ex )
                    {
                        throw new MojoExecutionException( "Error Deploying artifact", ex );
                    }
                }
                finally
                {
                    if ( moduleJarMinusCP != null )
                    {
                        moduleJarMinusCP.delete();
                    }
                }
            }
        }
        finally
        {
            /*if ( searcher != null )
            {
                try
                {
                    searcher.close();
                }
                catch ( IOException ex )
                {
                    getLog().error( ex );
                }
            }*/
        }

        //process collected non-recognized external jars..
        if ( externals.size() > 0 )
        {
            index = 0;
            count = externals.size();
            for ( ExternalsWrapper ex : externals )
            {
                Artifact art = createArtifact( ex.getArtifact(), ex.getVersion(), ex.getGroupid() );
                index = index + 1;
                getLog().info( "Processing external " + index + "/" + count );
                File pom = createExternalProject( ex );
                ArtifactMetadata metadata = new ProjectArtifactMetadata( art, pom );
                art.addMetadata( metadata );
                if ( !skipLocalInstall )
                {
                    install( ex.getFile(), art );
                }
                try
                {
                    if ( deploymentRepository != null )
                    {
                        artifactDeployer.deploy( ex.getFile(), art,
                            deploymentRepository, localRepository );
                    }
                }
                catch ( ArtifactDeploymentException exc )
                {
                    throw new MojoExecutionException( "Error Deploying artifact", exc );
                }
            }
        }

        if ( ! defineCluster )
        {
            getLog().info( "Not creating cluster POMs." );
        }
        else if ( forcedVersion == null )
        {
            getLog().warn( "Version not specified, cannot create cluster POMs." );
        }
        else
        {
            for ( Map.Entry<String, Collection<ModuleWrapper>> elem : clusters.entrySet() )
            {
                String cluster = stripClusterName( elem.getKey() );
                Collection<ModuleWrapper> modules = elem.getValue();
                getLog().info( "Processing cluster " + cluster );
                Artifact art = createClusterArtifact( cluster, forcedVersion );
                File pom = createClusterProject( art, modules );
                ProjectArtifactMetadata metadata = new ProjectArtifactMetadata( art, pom );
                art.addMetadata( metadata );
                if ( !skipLocalInstall )
                {
                    install( pom, art );
                }
                try
                {
                    if ( deploymentRepository != null )
                    {
                        artifactDeployer.deploy( pom, art, deploymentRepository, localRepository );
                    }
                }
                catch ( ArtifactDeploymentException ex )
                {
                    throw new MojoExecutionException( "Error Deploying artifact", ex );
                }
            }

        }
    }

    void install( File file, Artifact art )
        throws MojoExecutionException
    {
        assert localRepository != null;
        try
        {
            artifactInstaller.install( file, art, localRepository );
        }
        catch ( ArtifactInstallationException e )
        {
            // TODO: install exception that does not give a trace
            throw new MojoExecutionException( "Error installing artifact", e );
        }
    }

    //performs the same tasks as the MavenProjectHelper
    Artifact createAttachedArtifact( Artifact primary, File file, String type, String classifier )
    {
        assert type != null;

        ArtifactHandler handler;

        handler = artifactHandlerManager.getArtifactHandler( type );

        if ( handler == null )
        {
            getLog().warn( "No artifact handler for " + type );
            handler = artifactHandlerManager.getArtifactHandler( "jar" );
        }

        Artifact artifact = new AttachedArtifact( primary, type, classifier, handler );

        artifact.setFile( file );
        artifact.setResolved( true );
        return artifact;
    }

    private File createMavenProject( ModuleWrapper wrapper, List<ModuleWrapper> wrapperList,
                                     List<ExternalsWrapper> externalsList, IndexSearcher searcher )
            throws MojoExecutionException
    {
        Model mavenModel = new Model();

        mavenModel.setGroupId( wrapper.getGroup() );
        mavenModel.setArtifactId( wrapper.getArtifact() );
        mavenModel.setVersion( wrapper.getVersion() );
        mavenModel.setPackaging( "jar" );
        mavenModel.setModelVersion( "4.0.0" );
        if ( artefactParent != null ) {
            mavenModel.setParent( artefactParent );
        }
        ExamineManifest man = wrapper.getModuleManifest();
        List<Dependency> deps = new ArrayList<Dependency>();
        if ( !man.getDependencyTokens().isEmpty() )
        {
            for ( String elem : man.getDependencyTokens() )
            {
                // create pseudo wrapper
                ModuleWrapper wr = new ModuleWrapper( elem );
                int index = wrapperList.indexOf( wr );
                if ( index > -1 )
                {
                    wr = wrapperList.get( index );
                    Dependency dep = new Dependency();
                    dep.setArtifactId( wr.getArtifact() );
                    dep.setGroupId( wr.getGroup() );
                    dep.setVersion( wr.getVersion() );
                    dep.setType( "jar" );
                    //we don't want the API modules to depend on non-api ones..
                    // otherwise the transitive dependency mechanism pollutes your classpath..
                    if ( wrapper.getModuleManifest().hasPublicPackages() && !wr.getModuleManifest().hasPublicPackages() )
                    {
                        dep.setScope( "runtime" );
                    }
                    deps.add( dep );
                }
                else if ( dependencyRepositoryUrl != null )
                {
                    Dependency dep = new Dependency();
                    dep.setType( "jar" );
                    String artifactId = elem.replace( '.', '-' );
                    dep.setArtifactId( artifactId );
                    if ( forcedVersion == null )
                    {
                        throw new MojoExecutionException( "Cannot use dependencyRepositoryUrl without forcedVersion" );
                    }
                    dep.setVersion( forcedVersion );
                    ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy();
                    List<ArtifactRepository> repos = Collections.singletonList(
                            repositoryFactory.createArtifactRepository( dependencyRepositoryId, dependencyRepositoryUrl, artifactRepositoryLayout, policy, policy) );
                    try
                    {
                        artifactResolver.resolve( artifactFactory.createBuildArtifact( groupIdPrefix + GROUP_API, artifactId, forcedVersion, "pom" ), repos, localRepository );
                        dep.setGroupId( groupIdPrefix + GROUP_API );
                    }
                    catch ( AbstractArtifactResolutionException x )
                    {
                        try
                        {
                            artifactResolver.resolve( artifactFactory.createBuildArtifact( groupIdPrefix + GROUP_IMPL, artifactId, forcedVersion, "pom" ), repos, localRepository );
                            dep.setGroupId( groupIdPrefix + GROUP_IMPL );
                            if ( wrapper.getModuleManifest().hasPublicPackages() )
                            {
                                dep.setScope( "runtime" );
                            }
                        }
                        catch ( AbstractArtifactResolutionException x2 )
                        {
                            try
                            {
                                artifactResolver.resolve( artifactFactory.createBuildArtifact( groupIdPrefix + GROUP_EXTERNAL, artifactId, forcedVersion, "pom" ), repos, localRepository );
                                dep.setGroupId( groupIdPrefix + GROUP_EXTERNAL );
                                if ( wrapper.getModuleManifest().hasPublicPackages() )
                                {
                                    dep.setScope( "runtime" );
                                }
                            }
                            catch ( AbstractArtifactResolutionException x3 )
                            {
                                getLog().warn( x3.getOriginalMessage() );
                                throw new MojoExecutionException( "No module found for dependency '" + elem + "'", x );
                            }

                           
                        }

                    }
                    deps.add( dep );
                }
                else
                {
                    getLog().warn( "No module found for dependency '" + elem + "'" );
                }
            }
        }
        //need some generic way to handle Classpath: items.
        //how to figure the right version?
        String cp = wrapper.getModuleManifest().getClasspath();
        if ( !cp.isEmpty() )
        {
            StringTokenizer tok = new StringTokenizer( cp );
            while ( tok.hasMoreTokens() )
            {
                String path = tok.nextToken();
                File f = new File( wrapper.getFile().getParentFile(), path );
                if ( f.exists() )
                {
                    Dependency dep = findExternal( searcher, f );
                    if ( dep != null )
                    {
                        deps.add( dep );
                        // XXX MNBMODULE-170: repack NBM with *.external
                    }
                    else
                    {
                        ExternalsWrapper ex = new ExternalsWrapper();
                        ex.setFile( f );
                        String artId = f.getName();
                        if ( artId.endsWith( ".jar" ) )
                        {
                            artId = artId.substring( 0, artId.length() - ".jar".length() );
                        }
                        ex.setVersion( wrapper.getVersion() );
                        ex.setArtifact( artId );
                        ex.setGroupid( groupIdPrefix + GROUP_EXTERNAL );
                        externalsList.add( ex );
                        dep = new Dependency();
                        dep.setArtifactId( artId );
                        dep.setGroupId( groupIdPrefix + GROUP_EXTERNAL );
                        dep.setVersion( wrapper.getVersion() );
                        dep.setType( "jar" );
                        deps.add( dep );
                    }
                }
            }
        }

        wrapper.deps = deps;
        mavenModel.setDependencies( deps );
        FileWriter writer = null;
        File fil = null;
        try
        {
            MavenXpp3Writer xpp = new MavenXpp3Writer();
            fil = File.createTempFile( "maven", ".pom" );
            fil.deleteOnExit();
            writer = new FileWriter( fil );
            xpp.write( writer, mavenModel );
        }
        catch ( IOException ex )
        {
            ex.printStackTrace();

        }
        finally
        {
            if ( writer != null )
            {
                try
                {
                    writer.close();
                }
                catch ( IOException io )
                {
                    io.printStackTrace();
                }
            }
        }
        return fil;
    }

    private Dependency findExternal( IndexSearcher searcher, File f )
    {
        if ( searcher == null )
        {
            return null;
        }
        try
        {
            MessageDigest shaDig = MessageDigest.getInstance( "SHA1" );
            InputStream is = new FileInputStream( f );
            try {
                OutputStream os = new DigestOutputStream( new NullOutputStream(), shaDig );
                IOUtil.copy( is, os );
                os.close();
            }
            finally
            {
                is.close();
            }
            String sha = encode( shaDig.digest() );
            TermQuery q = new TermQuery( new Term( "1", sha ) );
            TopScoreDocCollector collector = TopScoreDocCollector.create( 5 );
            searcher.search(q, collector);
            ScoreDoc[] hits = collector.topDocs().scoreDocs;
            if ( hits.length >= 1 )
            {
                int docId = hits[0].doc;    
                Document doc = searcher.doc(docId);                
                IndexableField idField = doc.getField( "u" );
                if ( idField != null )
                {
                    String id = idField.stringValue();
                    String[] splits = StringUtils.split( id, "|" );
                    Dependency dep = new Dependency();
                    dep.setArtifactId( splits[1] );
                    dep.setGroupId( splits[0] );
                    dep.setVersion( splits[2] );
                    dep.setType( "jar" );
                    if ( splits.length > 3 && !"NA".equals( splits[3] ) )
                    {
                        dep.setClassifier( splits[3] );
                    }
                    getLog().info( "found match " + splits[0] + ":" + splits[1] + ":" + splits[2] + " for " + f.getName() );
                    return dep;
                }
                else
                {
                    getLog().error( "no idField for " + q );
                }
            }
            else
            {
                getLog().info( "no repository match for " + f.getName() );
            }
        }
        catch ( Exception x )
        {
            getLog().error( x );
        }
        return null;
    }

    File createExternalProject( ExternalsWrapper wrapper )
    {
        Model mavenModel = new Model();

        mavenModel.setGroupId( wrapper.getGroupid() );
        mavenModel.setArtifactId( wrapper.getArtifact() );
        mavenModel.setVersion( wrapper.getVersion() );
        mavenModel.setPackaging( "jar" );
        mavenModel.setModelVersion( "4.0.0" );
        if ( artefactParent != null ) {
            mavenModel.setParent( artefactParent );
        }
        mavenModel.setName( 
            "Maven definition for " + wrapper.getFile().getName() + " - external part of NetBeans module." );
        mavenModel.setDescription( 
            "POM and identification for artifact that was not possible to uniquely identify as a maven dependency." );
        FileWriter writer = null;
        File fil = null;
        try
        {
            MavenXpp3Writer xpp = new MavenXpp3Writer();
            fil = File.createTempFile( "maven", ".pom" );
            fil.deleteOnExit();
            writer = new FileWriter( fil );
            xpp.write( writer, mavenModel );
        }
        catch ( IOException ex )
        {
            ex.printStackTrace();
        }
        finally
        {
            if ( writer != null )
            {
                try
                {
                    writer.close();
                }
                catch ( IOException io )
                {
                    io.printStackTrace();
                }
            }
        }
        return fil;

    }

    private File createClusterProject( Artifact cluster, Collection<ModuleWrapper> mods )
    {
        Model mavenModel = new Model();

        mavenModel.setGroupId( cluster.getGroupId() );
        mavenModel.setArtifactId( cluster.getArtifactId() );
        mavenModel.setVersion( cluster.getVersion() );
//        mavenModel.setPackaging("nbm-application");
        mavenModel.setPackaging( "pom" );
        mavenModel.setModelVersion( "4.0.0" );
        if ( artefactParent != null ) {
            mavenModel.setParent( artefactParent );
        }
        List<Dependency> deps = new ArrayList<Dependency>();
        for ( ModuleWrapper wr : mods )
        {
            Dependency dep = new Dependency();
            dep.setArtifactId( wr.getArtifact() );
            dep.setGroupId( wr.getGroup() );
            dep.setVersion( wr.getVersion() );
            if ( wr.getModuleManifest().isNetBeansModule() )
            {
                dep.setType( "nbm-file" );
            }
            deps.add( dep );
        }
        mavenModel.setDependencies( deps );
//        
//        
//        Build build = new Build();
//        Plugin plg = new Plugin();
//        plg.setGroupId("org.codehaus.mojo");
//        plg.setArtifactId("nbm-maven-plugin");
//        plg.setVersion("2.7-SNAPSHOT");
//        plg.setExtensions(true);
//        build.addPlugin(plg);
//        mavenModel.setBuild(build);

        FileWriter writer = null;
        File fil = null;
        try
        {
            MavenXpp3Writer xpp = new MavenXpp3Writer();
            fil = File.createTempFile( "maven", ".pom" );
            fil.deleteOnExit();
            writer = new FileWriter( fil );
            xpp.write( writer, mavenModel );
        }
        catch ( IOException ex )
        {
            ex.printStackTrace();
        }
        finally
        {
            IOUtil.close( writer );
        }
        return fil;
    }

    Artifact createArtifact( String artifact, String version, String group )
    {
        return artifactFactory.createBuildArtifact( group, artifact, version, "jar" );
    }

    private Artifact createClusterArtifact( String artifact, String version )
    {
        return artifactFactory.createBuildArtifact( groupIdPrefix + GROUP_CLUSTER, artifact, version, "pom" );
    }

    private static Pattern PATTERN_CLUSTER = Pattern.compile( "([a-zA-Z]+)[0-9\\.]*" );
    static String stripClusterName( String key )
    {
        Matcher m = PATTERN_CLUSTER.matcher( key );
        if ( m.matches() )
        {
            return m.group( 1 );
        }
        return key;
    }

    private static class ExternalsWrapper
    {

        private File file;

        private String artifact;

        private String groupid;

        public String getArtifact()
        {
            return artifact;
        }

        public void setArtifact( String artifact )
        {
            this.artifact = artifact;
        }

        public File getFile()
        {
            return file;
        }

        public void setFile( File file )
        {
            this.file = file;
        }

        public String getGroupid()
        {
            return groupid;
        }

        public void setGroupid( String groupid )
        {
            this.groupid = groupid;
        }

        public String getVersion()
        {
            return version;
        }

        public void setVersion( String version )
        {
            this.version = version;
        }
        private String version;

    }

    private static class ModuleWrapper
    {

        ExamineManifest man;

        private String artifact;

        private String version;

        private String group;

        private File file;

        private String cluster;

        String module;

        List<Dependency> deps;

        public ModuleWrapper( String module )
        {
            this.module = module;
        }

        public ModuleWrapper( String art, String ver, String grp, ExamineManifest manifest, File fil )
        {
            man = manifest;
            artifact = art;
            version = ver;
            group = grp;
            file = fil;
        }

        @Override
        public int hashCode()
        {
            return getModule().hashCode();
        }

        @Override
        public boolean equals( Object obj )
        {
            return obj instanceof ModuleWrapper && getModule().equals( ( (ModuleWrapper) obj ).getModule() );
        }

        public String getModule()
        {
            return module != null ? module : getModuleManifest().getModule();
        }

        public ExamineManifest getModuleManifest()
        {
            return man;
        }

        private String getArtifact()
        {
            return artifact;
        }

        private String getVersion()
        {
            return version;
        }

        private String getGroup()
        {
            return group;
        }

        private File getFile()
        {
            return file;
        }

        void setCluster( String clust )
        {
            cluster = clust;
        }

        String getCluster()
        {
            return cluster;
        }
    }

    private static class NullOutputStream
        extends OutputStream
    {

        @Override
        public void write( int b )
            throws IOException
        {
        }
    }

    /**
     * Encodes a 128 bit or 160-bit byte array into a String.
     *
     * @param binaryData Array containing the digest
     * @return Encoded hex string, or null if encoding failed
     */
    static String encode( byte[] binaryData )
    {
        int bitLength = binaryData.length * 8;
        if ( bitLength != 128 && bitLength != 160 )
        {
            throw new IllegalArgumentException(
                "Unrecognised length for binary data: " + bitLength + " bits" );
        }
        return String.format( "%0" + bitLength / 4 + "x", new BigInteger( 1, binaryData ) );
    }
}
