/* ==========================================================================
 * 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.setGroupId( 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 ) );
    }
}
