package org.apache.netbeans.nbm;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import com.google.common.collect.Sets;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.netbeans.nbm.utils.ExamineManifest;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.filters.StringInputStream;
import org.apache.tools.ant.taskdefs.Chmod;
import org.apache.tools.ant.types.FileSet;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.io.InputStreamFacade;
import org.netbeans.nbbuild.MakeListOfNBM;

/**
 * Create the NetBeans module clusters/application for the 'nbm-application' packaging
 * projects
 *
 * @author Milos Kleint
 */
@Mojo( name = "cluster-app", 
        defaultPhase = LifecyclePhase.PACKAGE,
        requiresProject = true, 
        threadSafe = true,
        requiresDependencyResolution = ResolutionScope.RUNTIME )
public class CreateClusterAppMojo
    extends AbstractNbmMojo
{

    /**
     * output directory where the the NetBeans application will be created.
     */
    @Parameter( defaultValue = "${project.build.directory}", required = true )
    private File outputDirectory;

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

    /**
     * The branding token for the application based on NetBeans platform.
     */
    @Parameter( property = "netbeans.branding.token", required = true )
    protected String brandingToken;

    /**
     * Optional path to custom etc/${brandingToken}.conf file. If not defined,
     * a default template will be used.
     */
    @Parameter( property = "netbeans.conf.file" )
    private File etcConfFile;

    /**
     * Optional path to custom etc/${brandingToken}.clusters file. If not defined,
     * a default one will be generated.
     */
    @Parameter( property = "netbeans.clusters.file" )
    private File etcClustersFile;

    /**
     * Directory which contains the executables that will be copied to
     * the final application's bin/ directory.
     * Please note that the name of the executables shall generally
     * match the brandingToken parameter. Otherwise the application can be wrongly branded.
     */
    @Parameter( property = "netbeans.bin.directory" )
    private File binDirectory;

    /**
     * If the depending NBM file doesn't contain any application cluster information,
     * use this value as default location for such module NBMs.
     * @since 3.2
     */
    @Parameter( defaultValue = "extra" )
    private String defaultCluster;
    
    /**
     * attempts to verify the integrity of module artifacts making sure that all dependencies are included
     * and that all required tokens are provided
     * @since 3.10
     */
    @Parameter( defaultValue = "true", property = "netbeans.verify.integrity" )
    private boolean verifyIntegrity;
    
    /**
     * @since 4.12
     */
    @Parameter( defaultValue = "org.netbeans", property = "groupIdPrefix" )
    private String groupIdPrefix;
    
    private final Collection<String> defaultPlatformTokens = Arrays.asList( new String[] {
                    "org.openide.modules.os.Windows",
                    "org.openide.modules.os.Unix",
                    "org.openide.modules.os.MacOSX",
                    "org.openide.modules.os.OS2",
                    "org.openide.modules.os.PlainUnix",    
                    "org.openide.modules.os.Linux",
                    "org.openide.modules.os.Solaris",
                    "org.openide.modules.ModuleFormat1",
                    "org.openide.modules.ModuleFormat2",
                    "org.openide.modules.jre.JavaFX" //MNBMODULE-234
    } );


    // <editor-fold defaultstate="collapsed" desc="Component parameters">
    
    @Component
    private ArtifactFactory artifactFactory;

    @Component
    private ArtifactResolver artifactResolver;

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

// end of component params custom code folding
// </editor-fold>

    @Override
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {

        File nbmBuildDirFile = new File( outputDirectory, brandingToken );
        if ( !nbmBuildDirFile.exists() )
        {
            nbmBuildDirFile.mkdirs();
        }

        if ( "nbm-application".equals( project.getPackaging() ) )
        {
            Project antProject = registerNbmAntTasks();

            Set<String> wrappedBundleCNBs = new HashSet<>( 100 );
            Map<String, Set<String>> clusterDependencies = new HashMap<>();
            Map<String, Set<String>> clusterModules = new HashMap<>();
            
            //verify integrity
            Set<String> modulesCNBs = new HashSet<>( 200 );
            Set<String> dependencyCNBs = new HashSet<>( 200 );
            Map<String, Set<String>> dependencyCNBBacktraces = new HashMap<>( 50 );
            Set<String> requireTokens = new HashSet<>( 50 );
            Map<String, Set<String>> requireTokensBacktraces = new HashMap<>( 50 );
            Set<String> provideTokens = new HashSet<>( 50 );
            Set<String> osgiImports = new HashSet<>( 50 );
            Map<String, Set<String>> osgiImportsBacktraces = new HashMap<>( 50 );
            Set<String> osgiExports = new HashSet<>( 50 );
            Set<String> osgiExportsSubs = new HashSet<>( 50 ); //a way to deal with nb module declaring xxx.** (subpackages) declaration that is consumed by osgi imports
            
            List<BundleTuple> bundles = new ArrayList<>();

            @SuppressWarnings( "unchecked" )
            Set<Artifact> artifacts = project.getArtifacts();
            for ( Artifact art : artifacts )
            {
                ArtifactResult res = turnJarToNbmFile( art, artifactFactory, artifactResolver, project, localRepository );
                if ( res.hasConvertedArtifact() )
                {
                    art = res.getConvertedArtifact();
                }

                if ( art.getType().equals( "nbm-file" ) )
                {
                    try
                    {
                        JarFile jf = new JarFile( art.getFile() );
                        try
                        {
                            String clusterName = findCluster( jf );
                            ClusterTuple cluster = processCluster( clusterName, nbmBuildDirFile, art );
                            
                                getLog().debug( "Copying " + art.getId() + " to cluster " + clusterName );
                                Enumeration<JarEntry> enu = jf.entries();

                                // we need to trigger this ant task to generate the update_tracking file.
                                MakeListOfNBM makeTask = (MakeListOfNBM) antProject.createTask( "genlist" );
                                antProject.setNewProperty( "module.name", art.getFile().getName() ); // TODO
                                antProject.setProperty( "cluster.dir", clusterName );
                                FileSet set = makeTask.createFileSet();
                                set.setDir( cluster.location );
                                makeTask.setOutputfiledir( cluster.location );
                                String[] executables = null;
                                File classpathRoot = null;
                                String classPath = null;
                                while ( enu.hasMoreElements() )
                                {
                                    JarEntry ent = enu.nextElement();
                                    String name = ent.getName();
                                    //MNBMODULE-176
                                    if ( name.equals( "Info/executables.list" ) )
                                    {
                                        if ( cluster.newer )
                                        {
                                            InputStream is = jf.getInputStream( ent );
                                            executables = StringUtils.split( IOUtil.toString( is, "UTF-8" ), "\n" );
                                        }
                                    }
                                    else if ( name.startsWith( "netbeans/" ) )
                                    { // ignore everything else.
                                        String path = clusterName + name.substring( "netbeans".length() );
                                        boolean ispack200 = path.endsWith( ".jar.pack.gz" );
                                        if ( ispack200 )
                                        {
                                            path = path.replace( ".jar.pack.gz", ".jar" );
                                        }
                                        File fl = new File( nbmBuildDirFile, path.replace( "/", File.separator ) );
                                        String part = name.substring( "netbeans/".length() );
                                        if ( ispack200 )
                                        {
                                            part = part.replace( ".jar.pack.gz", ".jar" );
                                        }
                                        if ( cluster.newer )
                                        {
                                            if ( ent.isDirectory() )
                                            {
                                                fl.mkdirs();
                                            }
                                            else if ( path.endsWith( ".external" ) ) // MNBMODULE-138
                                            {
                                                InputStream is = jf.getInputStream( ent );
                                                try
                                                {
                                                    externalDownload( new File( fl.getParentFile(),
                                                                                fl.getName().replaceFirst( "[.]external$",
                                                                                                           "" ) ), is );
                                                }
                                                finally
                                                {
                                                    is.close();
                                                }
                                                //MNBMODULE-192
                                                set.appendIncludes( new String[] { name.substring( "netbeans/".length(), name.length() - ".external".length() ) } );
                                            }
                                            else
                                            {
                                                set.appendIncludes( new String[] { part } );

                                                fl.getParentFile().mkdirs();
                                                fl.createNewFile();
                                                BufferedOutputStream outstream = null;
                                                try
                                                {
                                                    outstream = new BufferedOutputStream( new FileOutputStream( fl ) );
                                                    InputStream instream = jf.getInputStream( ent );
                                                    if ( ispack200 )
                                                    {
                                                        Pack200.Unpacker unp = Pack200.newUnpacker();
                                                        JarOutputStream jos = new JarOutputStream( outstream );
                                                        GZIPInputStream gzip = new GZIPInputStream( instream );
                                                        try
                                                        {
                                                            unp.unpack( gzip, jos );
                                                        }
                                                        finally
                                                        {
                                                            jos.close();
                                                        }
                                                    }
                                                    else
                                                    {
                                                        IOUtil.copy( instream, outstream );
                                                    }
                                                }
                                                finally
                                                {
                                                    IOUtil.close( outstream );
                                                }
                                            }
                                        }
                                            
                                            //TODO examine netbeans/config/Modules to see if the module is autoload/eager
                                            // in verifyIntegrity these could be handled more gracefully than regular modules.
                                            //eager is simpler, does not need to have module dependencies satisfied.
                                            //autoload needs checking if any of the other modules declares a dependency on it. if not, also safe to ignore?
                                            
                                            
                                            // now figure which one of the jars is the module jar..
                                            if ( part.matches( "(modules|core|lib)/[^/]+[.]jar" ) )
                                            {
                                                ExamineManifest ex = new ExamineManifest( getLog() );
                                                ex.setJarFile( fl );
                                                ex.setPopulateDependencies( true );
                                                ex.checkFile();
                                                if ( ex.isNetBeansModule() )
                                                {
                                                    makeTask.setModule( part );
                                                    addToMap( clusterDependencies, clusterName, ex.getDependencyTokens() );
                                                    addToMap( clusterModules, clusterName, Collections.singletonList( ex.getModule() ) );
                                                    if ( ex.getClasspath().length() > 0 )
                                                    { //MNBMODULE-220
                                                        classPath = ex.getClasspath();
                                                        classpathRoot = fl.getParentFile();
                                                    }
                                                }
                                                if ( verifyIntegrity )
                                                {
                                                    dependencyCNBs.addAll( ex.getDependencyTokens() );
                                                    modulesCNBs.add( ex.getModule() );
                                                    for ( String d : ex.getDependencyTokens() )
                                                    {
                                                        addToMap( dependencyCNBBacktraces, d, Collections.singletonList( ex.getModule() ) );
                                                    }
                                                    if ( ex.isNetBeansModule() )
                                                    {
                                                        requireTokens.addAll( ex.getNetBeansRequiresTokens() );
                                                        for ( String r : ex.getNetBeansRequiresTokens() )
                                                        {
                                                            addToMap( requireTokensBacktraces, r, Collections.singletonList( ex.getModule() ) );
                                                        }
                                                        provideTokens.addAll( ex.getNetBeansProvidesTokens() );
                                                        for ( String pack : ex.getPackages() )
                                                        {
                                                            if ( pack.endsWith( ".**" ) )
                                                            {
                                                                //what to do with subpackages?
                                                                pack = pack.substring( 0, pack.length() - ".**".length() );
                                                                osgiExportsSubs.add( pack );
                                                            } 
                                                            else if ( pack.endsWith( ".*" ) )
                                                            {
                                                                pack = pack.substring( 0, pack.length() - ".*".length() );
                                                                osgiExports.add( pack );
                                                            }
                                                        }
                                                        
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    if ( classPath != null )
                                    { //MNBMODULE-220 collect wrappedbundleCNBs, later useful in assignClustersToBundles(), these get removed from list of bundles.
                                        String[] paths = StringUtils.split( classPath, " " );
                                        for ( String path : paths )
                                        {
                                            path = path.trim();
                                            File classpathFile = new File( classpathRoot, path );
                                            if ( path.equals( "${java.home}/lib/ext/jfxrt.jar" ) )
                                            { //MNBMODULE-228
                                                String jhm = System.getProperty( "java.home" );
                                                classpathFile = new File( new File( new File( new File( jhm ), "lib" ), "ext" ), "jfxrt.jar" );
                                                if ( !classpathFile.exists() )
                                                {
                                                    File jdk7 = new File( new File( new File( jhm ), "lib" ), "jfxrt.jar" );
                                                    if ( jdk7.exists() )
                                                    {
                                                        classpathFile = jdk7;
                                                    }
                                                }
                                            }
                                            if ( !classpathFile.isFile() )
                                            {
                                                getLog().warn( "Could not resolve Class-Path item in " + art.getId() + ", path is:" + path +  ", skipping" );
                                                continue; //try to guard against future failures
                                            }
                                            ExamineManifest ex = new ExamineManifest( getLog() );
                                            ex.setJarFile( classpathFile );
                                            //ex.setPopulateDependencies( true );
                                            ex.checkFile();
                                            if ( ex.isOsgiBundle() )
                                            {
                                                if ( art.getId().contains( groupIdPrefix + ".modules:org-netbeans-modules-maven-embedder" ) )
                                                {
                                                    // in this case we dont want module-maven-embedder to be considered as wrapper for his libs                                                     
                                                    // guava is provided but ide have it also 
                                                }
                                                else
                                                {
                                                    getLog().info( ex.getModule() + " added by " + art.getId() + "" + classpathFile );
                                                    wrappedBundleCNBs.add( ex.getModule() );
                                                }
                                            }
                                        }
                                    }
                            if ( cluster.newer )
                            {
                                try
                                {
                                    makeTask.execute();
                                }
                                catch ( BuildException e )
                                {
                                    getLog().error( "Cannot Generate update_tracking XML file from " + art.getFile() );
                                    throw new MojoExecutionException( e.getMessage(), e );
                                }

                                if ( executables != null )
                                {
                                    //MNBMODULE-176
                                    for ( String exec : executables )
                                    {
                                        exec = exec.replace( "/", File.separator );
                                        File execFile = new File( cluster.location, exec );
                                        if ( execFile.exists() )
                                        {
                                            execFile.setExecutable( true, false );
                                        }
                                    }
                                }
                            }
                            
                        }
                        finally
                        {
                            jf.close();
                        }
                    }
                    catch ( IOException ex )
                    {
                        getLog().error( art.getFile().getAbsolutePath(), ex );
                    }
                }
                if ( res.isOSGiBundle() )
                {
                    ExamineManifest ex = res.getExaminedManifest();
                    bundles.add( new BundleTuple( art, ex ) );
                    if ( verifyIntegrity ) 
                    {
                        dependencyCNBs.addAll( ex.getDependencyTokens() );
                        for ( String d : ex.getDependencyTokens() )
                        {
                            addToMap( dependencyCNBBacktraces, d, Collections.singletonList( ex.getModule() ) );
                        }
                        modulesCNBs.add( ex.getModule() );
                        osgiImports.addAll( ex.getOsgiImports() );
                        for ( String d : ex.getOsgiImports() )
                        {
                            addToMap( osgiImportsBacktraces, d, Collections.singletonList( ex.getModule() ) );
                        }
                        
                        osgiExports.addAll( ex.getOsgiExports() );
                    }
                } 
            }
            
            if ( verifyIntegrity )
            {
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "All found codenamebases:" + Arrays.toString( modulesCNBs.toArray() ) );
                    getLog().debug( "All found OSGI exports:" + Arrays.toString( osgiExports.toArray() ) );
                    getLog().debug( "All found provided tokens:" + Arrays.toString( provideTokens.toArray() ) );
                }
                dependencyCNBs.removeAll( modulesCNBs );
                if ( modulesCNBs.contains( "org.netbeans.modules.netbinox" ) )
                {
                    dependencyCNBs.remove( "org.eclipse.osgi" ); //this is special.
                }
                osgiImports.removeAll( osgiExports );
                Iterator<String> it = osgiImports.iterator();
                while ( it.hasNext() )
                {
                    String s = it.next();
                    if ( s.startsWith( "java." ) 
                            || s.startsWith( "javax." ) 
                            || s.startsWith( "sun." ) 
                            || s.startsWith( "org.xml.sax" ) 
                            || s.startsWith( "org.w3c.dom" ) 
                            || s.startsWith( "org.ietf.jgss" ) )
                    {
                        it.remove();
                        continue;
                    }
                    for ( String sub : osgiExportsSubs )
                    {
                        if ( s.startsWith( sub ) )
                        {
                            it.remove();
                            break;
                        }
                    }
                }
                requireTokens.removeAll( provideTokens );
                requireTokens.removeAll( defaultPlatformTokens );
                if ( !dependencyCNBs.isEmpty() || !osgiImports.isEmpty() || !requireTokens.isEmpty() )
                {
                    if ( !dependencyCNBs.isEmpty() )
                    {
                        getLog().error( "Some included modules/bundles depend on these codenamebases but they are not included. The application will fail starting up. The missing codenamebases are:" );
                        for ( String s : dependencyCNBs )
                        {
                            Set<String> back = dependencyCNBBacktraces.get( s );
                            getLog().error( "   " + s + ( back != null ? "          ref: " + Arrays.toString( back.toArray() ) : "" ) );
                        }
                    }
                    if ( !osgiImports.isEmpty() )
                    {
                        getLog().error( "Some OSGi imports are not satisfied by included bundles' exports. The application will fail starting up. The missing imports are:" );
                        for ( String s : osgiImports )
                        {
                            Set<String> back = osgiImportsBacktraces.get( s );
                            getLog().error( "   " + s + ( back != null ? "          ref: " + Arrays.toString( back.toArray() ) : "" ) );
                        }
                    }
                    if ( !requireTokens.isEmpty() )
                    {
                        getLog().error( "Some tokens required by included modules are not provided by included modules. The application will fail starting up. The missing tokens are:" );
                        for ( String s : requireTokens )
                        {
                            Set<String> back = requireTokensBacktraces.get( s );
                            getLog().error( "   " + s + ( back != null ? "          ref: " + Arrays.toString( back.toArray() ) : "" ) );
                        }
                    }
                    throw new MojoFailureException( "See above for consistency validation check failures. Either fix those by adding the relevant dependencies to the application or disable the check by setting the verifyIntegrity parameter to false or by running with -Dnetbeans.verify.integrity=false cmd line parameter." );
                }
                else
                {
                    getLog().info( "Integrity verification passed." );
                }
            }
            else
            {
                getLog().info( "Integrity verification skipped." );
            }

            //attempt to sort clusters based on the dependencies and cluster content.
            Map<String, Set<String>> cluster2depClusters = computeClusterOrdering( clusterDependencies, clusterModules );
            clusterModules.clear();

            //now assign the cluster to bundles based on dependencies..
            assignClustersToBundles( bundles, wrappedBundleCNBs, clusterDependencies, cluster2depClusters, getLog() );


            for ( BundleTuple ent : bundles )
            {
                Artifact art = ent.artifact;
                final ExamineManifest ex = ent.manifest;

                String clstr = ent.cluster;
                if ( clstr == null )
                {
                    clstr = defaultCluster;
                }
                
                ClusterTuple cluster = processCluster( clstr, nbmBuildDirFile, art );
                if ( cluster.newer )
                {
                    getLog().info( "Copying " + art.getId() + " to cluster " + clstr );
                    File modules = new File( cluster.location, "modules" );
                    modules.mkdirs();
                    File config = new File( cluster.location, "config" );
                    File confModules = new File( config, "Modules" );
                    confModules.mkdirs();
                    File updateTracking = new File( cluster.location, "update_tracking" );
                    updateTracking.mkdirs();
                    final String cnb = ex.getModule();
                    final String cnbDashed = cnb.replace( ".", "-" );
                    final File moduleArt = new File( modules, cnbDashed + ".jar" ); //do we need the file in some canotical name pattern?
                    final String specVer = ex.getSpecVersion();
                    try
                    {
                        FileUtils.copyFile( art.getFile(), moduleArt );
                        final File moduleConf = new File( confModules, cnbDashed + ".xml" );
                        FileUtils.copyStreamToFile( new InputStreamFacade()
                        {
                            @Override
                            public InputStream getInputStream() throws IOException
                            {
                                return new StringInputStream( createBundleConfigFile( cnb, ex.isBundleAutoload() ), "UTF-8" );
                            }
                        }, moduleConf );
                        FileUtils.copyStreamToFile( new InputStreamFacade()
                        {
                            @Override
                            public InputStream getInputStream() throws IOException
                            {
                                return new StringInputStream( createBundleUpdateTracking( cnb, moduleArt, moduleConf, specVer ), "UTF-8" );
                            }
                        }, new File( updateTracking, cnbDashed + ".xml" ) );
                    }
                    catch ( IOException exc )
                    {
                        getLog().error( exc );
                    }
                }
            }

            getLog().info(
                "Created NetBeans module cluster(s) at " + nbmBuildDirFile.getAbsoluteFile() );

        }
        else
        {
            throw new MojoExecutionException(
                "This goal only makes sense on project with nbm-application packaging" );
        }
        //in 6.1 the rebuilt modules will be cached if the timestamp is not touched.
        File[] files = nbmBuildDirFile.listFiles();
        for ( File file : files )
        {
            if ( file.isDirectory() )
            {
                File stamp = new File( file, ".lastModified" );
                if ( !stamp.exists() )
                {
                    try
                    {
                        stamp.createNewFile();
                    }
                    catch ( IOException ex )
                    {
                        ex.printStackTrace();
                    }
                }
                stamp.setLastModified( new Date().getTime() );
            }
        }
        try
        {
            createBinEtcDir( nbmBuildDirFile, brandingToken );
        }
        catch ( IOException ex )
        {
            throw new MojoExecutionException(
                "Cannot process etc folder content creation.", ex );
        }
    }
    private static final Pattern PATT = Pattern.compile(
        ".*targetcluster=\"([a-zA-Z0-9_\\.\\-]+)\".*", Pattern.DOTALL );

    private String findCluster( JarFile jf )
        throws MojoFailureException, IOException
    {
        ZipEntry entry = jf.getEntry( "Info/info.xml" );
        InputStream ins = jf.getInputStream( entry );
        String str = IOUtil.toString( ins, "UTF8" );
        Matcher m = PATT.matcher( str );
        if ( !m.matches() )
        {
            getLog().info( "Cannot find cluster for " + jf.getName() + " Falling back to default value - '"
                               + defaultCluster + "'." );
            return defaultCluster;
        }
        else
        {
            return m.group( 1 );
        }
    }

    /**
     * 
     * @param buildDir Directory where the platform bundle is built
     * @param brandingToken
     * 
     * @throws java.io.IOException
     */
    private void createBinEtcDir( File buildDir, String brandingToken )
        throws IOException, MojoExecutionException
    {
        File etcDir = new File( buildDir + File.separator + "etc" );
        etcDir.mkdir();

        // create app.clusters which contains a list of clusters to include in the application

        File clusterConf = new File( etcDir + File.separator + brandingToken + ".clusters" );
        String clustersString;
        if ( etcClustersFile != null )
        {
            clustersString = FileUtils.fileRead( etcClustersFile, "UTF-8" );
        }
        else
        {
            clusterConf.createNewFile();
            StringBuilder buffer = new StringBuilder();
            File[] clusters = buildDir.listFiles( new FileFilter()
            {

                @Override
                public boolean accept( File pathname )
                {
                    return new File( pathname, ".lastModified" ).exists();
                }
            } );
            for ( File cluster : clusters )
            {
                buffer.append( cluster.getName() );
                buffer.append( "\n" );
            }
            clustersString = buffer.toString();
        }

        FileUtils.fileWrite( clusterConf.getAbsolutePath(), clustersString );

        File confFile = etcConfFile;
        String str;
        if ( confFile == null )
        {
            File harnessDir = new File( buildDir, "harness" );
            // app.conf contains default options and other settings
            confFile = new File(
                    harnessDir.getAbsolutePath() + File.separator + "etc" + File.separator + "app.conf" );
            if ( confFile.exists() )
            {
                str = FileUtils.fileRead( confFile, "UTF-8" );
            }
            else 
            {
                getLog().debug( "Using fallback app.conf shipping with the nbm-maven-plugin." );
                InputStream instream = null;
                try
                {
                    instream = getClass().getClassLoader().getResourceAsStream( "harness/etc/app.conf" );
                    str = IOUtil.toString( instream, "UTF-8" );
                }
                finally
                {
                    IOUtil.close( instream );
                }
            }
        }
        else
        {
            str = FileUtils.fileRead( confFile, "UTF-8" );
        }
        File confDestFile = new File(
            etcDir.getAbsolutePath() + File.separator + brandingToken + ".conf" );

        str = str.replace( "${branding.token}", brandingToken );
        FileUtils.fileWrite( confDestFile.getAbsolutePath(), "UTF-8", str );

        File destBinDir = new File( buildDir + File.separator + "bin" );
        destBinDir.mkdir();

        File binDir;
        File destExeW = new File( destBinDir, brandingToken + "_w.exe" );
        File destExe = new File( destBinDir, brandingToken + ".exe" );
        File destExe64 = new File( destBinDir, brandingToken + "64.exe" );
        File destSh = new File( destBinDir, brandingToken );

        if ( binDirectory != null )
        {
            //we have custom launchers.
            binDir = binDirectory;
            File[] fls = binDir.listFiles();
            if ( fls == null )
            {
                throw new MojoExecutionException( "Parameter 'binDirectory' has to point to an existing folder." );
            }
            for ( File fl : fls )
            {
                String name = fl.getName();
                File dest = null;
                if ( name.endsWith( "_w.exe" ) ) 
                {
                    dest = destExeW;
                }
                else if ( name.endsWith( "64.exe" ) )
                {
                    dest = destExe64;
                }
                else if ( name.endsWith( ".exe" ) )
                {
                    dest = destExe;
                }
                else if ( !name.contains( "." ) || name.endsWith( ".sh" ) )
                {
                    dest = destSh;
                }
                if ( dest != null  && fl.exists() ) //in 6.7 the _w.exe file is no more.
                {
                    FileUtils.copyFile( fl, dest );
                }
                else
                {
                    //warn about file not being copied
                }
            }
        }
        else
        {
            File harnessDir = new File( buildDir, "harness" );
            //we have org-netbeans-modules-apisupport-harness in target area, just use it's own launchers.
            binDir = new File(
                    harnessDir.getAbsolutePath() + File.separator + "launchers" );
            if ( binDir.exists() )
            {
                File exe = new File( binDir, "app.exe" );
                FileUtils.copyFile( exe, destExe );
                File exe64 = new File( binDir, "app64.exe" );
                if ( exe64.isFile() )
                {
                    FileUtils.copyFile( exe64, destExe64 );
                }
                File exew = new File( binDir, "app_w.exe" );
                if ( exew.exists() ) //in 6.7 the _w.exe file is no more.
                {
                    FileUtils.copyFile( exew, destExeW );
                }
                File sh = new File( binDir, "app.sh" );
                FileUtils.copyFile( sh, destSh );
            }
            else
            {
                File nbm = getHarnessNbm();
                try ( ZipFile zip = new ZipFile( nbm ) )
                {
                    getLog().debug( "Using fallback executables from downloaded org-netbeans-modules-apisupport-harness nbm file." );
                    writeFromZip( zip, "netbeans/launchers/app.sh",  destSh, true );
                    writeFromZip( zip, "netbeans/launchers/app.exe",  destExe, true );
                    writeFromZip( zip, "netbeans/launchers/app64.exe",  destExe64, false );
                    writeFromZip( zip, "netbeans/launchers/app_w.exe",  destExeW, false );
                }
            }
        }

        Project antProject = antProject();

        Chmod chmod = (Chmod) antProject.createTask( "chmod" );
        FileSet fs = new FileSet();
        fs.setDir( destBinDir );
        fs.setIncludes( "*" );
        chmod.addFileset( fs );
        chmod.setPerm( "755" );
        chmod.execute();
    }

    private void writeFile( String path, File destSh )
        throws IOException
    {
        InputStream instream = null;
        OutputStream output = null;
        try
        {
            instream = getClass().getClassLoader().getResourceAsStream( path );
            if ( instream == null )
            {
                throw new FileNotFoundException( path );
            }
            destSh.createNewFile();
            output = new BufferedOutputStream( new FileOutputStream( destSh ) );
            IOUtil.copy( instream, output );
        }
        finally
        {
            IOUtil.close( instream );
            IOUtil.close( output );
        }
    }

    private ClusterTuple processCluster( String cluster, File nbmBuildDirFile, Artifact art )
    {
        File clusterFile = new File( nbmBuildDirFile, cluster );
        boolean newer = false;
        if ( !clusterFile.exists() )
        {
            clusterFile.mkdir();
            newer = true;
        }
        else
        {
            File stamp = new File( clusterFile, ".lastModified" );
            if ( stamp.lastModified() < art.getFile().lastModified() )
            {
                newer = true;
            }
        }
        return new ClusterTuple( clusterFile, newer );
    }

        private void externalDownload( File f, InputStream is )
        throws IOException
    {
        // Cf. org.netbeans.nbbuild.AutoUpdate
        BufferedReader r = new BufferedReader( new InputStreamReader( is, "UTF-8" ) );
        long crc = -1;
        long size = -1;
        boolean found = false;
        String line;
        while ( ( line = r.readLine() ) != null )
        {
            if ( line.startsWith( "CRC:" ) )
            {
                crc = Long.parseLong( line.substring( 4 ).trim() );
            }
            else if ( line.startsWith( "URL:" ) )
            {
                String rest = line.substring(4).trim();
                if ( rest.startsWith( "m2:/" ) )
                {
                    if ( ! found )
                    {
                        String[] coords = rest.substring( 4 ).trim().split( ":" );
                        Artifact artifact;
                        if ( coords.length == 4 )
                        {
                            artifact = artifactFactory.createArtifact( coords[0], coords[1], coords[2], null, coords[3] );
                        }
                        else
                        {
                            artifact = artifactFactory.createArtifactWithClassifier( coords[0], coords[1], coords[2], coords[3], coords[4] );
                        }
                        try
                        {
                            artifactResolver.resolve( artifact, project.getRemoteArtifactRepositories(), localRepository );
                            FileUtils.copyFile( artifact.getFile(), f );
                            found = true;
                        }
                        catch ( AbstractArtifactResolutionException x )
                        {
                            getLog().warn( "Cannot find " + line.substring( 8 ), x );
                        }
                    }
                }
                else if ( ! found )
                {
                    String url = line.substring( 4 ).trim();
                    try
                    {
                        // XXX use Wagon API instead
                        FileUtils.copyURLToFile( new URL( url ), f );
                        found = true;
                    }
                    catch ( IOException x )
                    {
                        getLog().warn( "Cannot download " + url, x );
                    }
                }
            }
            else if ( line.startsWith( "SIZE:" ) )
            {
                size = Long.parseLong( line.substring( 5 ).trim() );
            }
            else
            {
                getLog().warn( "Unrecognized line: " + line );
            }
        }
        if ( ! found )
        {
            throw new IOException( "Could not download " + f );
        }
        if ( crc != -1 && crc != crcForFile( f ).getValue() )
        {
            throw new IOException( "CRC-32 of " + f + " does not match declared " + crc );
        }
        if ( size != -1 && size != f.length() )
        {
            throw new IOException( "Size of " + f + " does not match declared " + size );
        }
    }

    private File getHarnessNbm() throws MojoExecutionException
    {
        @SuppressWarnings( "unchecked" )
        Set<Artifact> artifacts = project.getArtifacts();
        String version = null;
        for ( Artifact a : artifacts )
        {
            if ( ( groupIdPrefix + ".modules" ).equals( a.getGroupId() ) && "org-netbeans-bootstrap".equals( a.getArtifactId() ) )
            {
                version = a.getBaseVersion(); //base version in non-snapshot should equals version, in snapshots to X-SNAPSHOT, not timestamp
                break;
            }
        }
        if ( version == null )
        {
            throw new MojoExecutionException( "We could not find org-netbeans-bootstrap among the modules in the application. Launchers could not be found." );
        }
        Artifact nbmArt = artifactFactory.createArtifact(
            groupIdPrefix + ".modules",
            "org-netbeans-modules-apisupport-harness",
            version,
            "compile",
            "nbm-file" );
        try
        {
            artifactResolver.resolve( nbmArt, project.getRemoteArtifactRepositories(), localRepository );
        }

        catch ( ArtifactResolutionException | ArtifactNotFoundException ex )
        {
            throw new MojoExecutionException( "Failed to retrieve the nbm file from repository", ex );
        }
        return nbmArt.getFile();
    }

    private void writeFromZip( final ZipFile zip, String zipPath, File destFile, boolean mandatory ) throws MojoExecutionException, IOException
    {
        final ZipEntry path = zip.getEntry( zipPath );
        if ( path == null )
        {
            if ( mandatory )
            {
                throw new MojoExecutionException( zipPath + " not found in " + zip.getName() );
            }
            getLog().debug( zipPath + " is not present in " + zip.getName() );
            return;
        }
        FileUtils.copyStreamToFile( new InputStreamFacade()
        {
            
            @Override
            public InputStream getInputStream() throws IOException
            {
                return zip.getInputStream( path );
            }
        }, destFile );
    }

    private static void addToMap( Map<String, Set<String>> map, String clusterName, List<String> newValues )
    {
        Set<String> lst = map.get( clusterName );
        if ( lst == null )
        {
            lst = new HashSet<>();
            map.put( clusterName, lst );
        }
        if ( newValues != null )
        {
            lst.addAll( newValues );
        }
    }
    
    private static List<String> findByDependencies( Map<String, Set<String>> clusterDependencies, String spec )
    {
        List<String> toRet = new ArrayList<>();
        for ( Map.Entry<String, Set<String>> entry : clusterDependencies.entrySet() )
        {
            if ( entry.getValue().contains( spec ) )
            {
                toRet.add( entry.getKey() );
            }
        }
        return toRet;
    }

    //the basic idea is that bundle's cluster can be determined by who depends on it.
    //simplest case is when a module depends on it. If there are more, we need to pick one that is "lower in the stack, that's what cluster2depClusters is for.
    //the rest needs to be determined in more sofisticated manner.
    //start from bundles with known cluster and see what other bundles they depend on. stamp all these with the same cluster. do it recursively.
    //At the end process the remaining bundles in reverse order. Check if *they* depend on a bundle with known cluster and so on..
    //A few unsolved cases:
    // - we never update the cluster information once a match was found, but there is a possibility that later in the processing the cluster could be "lowered".
    // - 2 or more modules from unrelated clusters we cannot easily decide, most likely should be in common denominator cluster but our cluster2depClusters map is not transitive, only lists direct dependencies
    static void assignClustersToBundles( List<BundleTuple> bundles, Set<String> wrappedBundleCNBs, Map<String, Set<String>> clusterDependencies, Map<String, Set<String>> cluster2depClusters, Log log )
    {
        List<BundleTuple> toProcess = new ArrayList<>();
        List<BundleTuple> known = new ArrayList<>();
        for ( Iterator<BundleTuple> it = bundles.iterator(); it.hasNext(); )
        {
            BundleTuple ent = it.next();
            Artifact art = ent.artifact;
            ExamineManifest ex = ent.manifest;
            String spec = ex.getModule();
            //null check for tests
            //have a way to force inclusion of osgi items. Direct dependency is never wrapped by modules.
            if ( art != null && art.getDependencyTrail().size() > 2 && wrappedBundleCNBs.contains( spec ) )
            {
                // we already have this one as a wrapped module.
                log.debug( "Not including bundle " + art.getDependencyConflictId()
                                    + ". It is already included in a NetBeans module" );
                it.remove();
                continue;
            }
            List<String> depclusters = findByDependencies( clusterDependencies, spec );
            if ( depclusters.size() == 1 )
            {
                ent.cluster = depclusters.get( 0 );
                known.add( ent );
            }
            else if ( depclusters.isEmpty() )
            {
                toProcess.add( ent );
            }
            else 
            {
                //more results.. from 2 dependent clusters pick the one that is lower in the stack.
                for ( Iterator<String> it2 = depclusters.iterator(); it2.hasNext(); )
                {
                    String s = it2.next();
                    Set<String> depsCs = cluster2depClusters.get( s );
                    boolean removeS = false;
                    for ( String sDep : depclusters )
                    {
                        if ( s.equals( sDep ) )
                        {
                            continue;
                        }
                        if ( depsCs != null && depsCs.contains( sDep ) )
                        {
                            removeS = true;
                        }
                    }
                    if ( removeS )
                    {
                        it2.remove();
                    }
                }
                ent.cluster = depclusters.get( 0 ); //TODO still some free room there, what if they don't directly depend on each other but still are related
                known.add ( ent );
            }
        }
        if ( !toProcess.isEmpty() )
        {
            walkKnownBundleDependenciesDown( known, toProcess );
        }
        if ( !toProcess.isEmpty() )
        {
            walkKnownBundleDependenciesUp( known, toProcess );
        }
    }

    private static void walkKnownBundleDependenciesDown( List<BundleTuple> known, List<BundleTuple> toProcess )
    {
        boolean atLeastOneWasFound = false;
        for ( Iterator<BundleTuple> it = toProcess.iterator(); it.hasNext(); )
        {
            BundleTuple bundleTuple = it.next();
            boolean found = false;
            for ( BundleTuple knownBT : known )
            {
                Sets.SetView<String> is = Sets.intersection( bundleTuple.manifest.getOsgiExports() , knownBT.manifest.getOsgiImports() );
                if ( !is.isEmpty() )
                {
                    found = true;
                    bundleTuple.cluster = knownBT.cluster;
                    break;
                }
                //dependencyTokens are requireBundle - matches the module property
                is = Sets.intersection( Collections.singleton( bundleTuple.manifest.getModule() ), new HashSet( knownBT.manifest.getDependencyTokens() ) );
                if ( !is.isEmpty() )
                {
                    found = true;
                    bundleTuple.cluster = knownBT.cluster;
                    break;
                }
                
            }
            if ( found )
            {
                atLeastOneWasFound = true;
                it.remove();
                known.add( bundleTuple );
            }
            
        }
        if ( !toProcess.isEmpty() && atLeastOneWasFound )
        {
            walkKnownBundleDependenciesDown( known, toProcess );
        }
    }

    private static void walkKnownBundleDependenciesUp( List<BundleTuple> known, List<BundleTuple> toProcess )
    {
        boolean atLeastOneWasFound = false;
        for ( Iterator<BundleTuple> it = toProcess.iterator(); it.hasNext(); )
        {
            BundleTuple bundleTuple = it.next();
            boolean found = false;
            for ( BundleTuple knownBT : known )
            {
                Sets.SetView<String> is = Sets.intersection( bundleTuple.manifest.getOsgiImports() , knownBT.manifest.getOsgiExports() );
                if ( !is.isEmpty() )
                {
                    found = true;
                    bundleTuple.cluster = knownBT.cluster;
                    break;
                }
                //dependencyTokens are requireBundle - matches the module property
                is = Sets.intersection( Collections.singleton( knownBT.manifest.getModule() ), new HashSet( bundleTuple.manifest.getDependencyTokens() ) );
                if ( !is.isEmpty() )
                {
                    found = true;
                    bundleTuple.cluster = knownBT.cluster;
                    break;
                }
                
            }
            if ( found )
            {
                atLeastOneWasFound = true;
                it.remove();
                known.add( bundleTuple );
            }
            
        }
        if ( !toProcess.isEmpty() && atLeastOneWasFound )
        {
            walkKnownBundleDependenciesDown( known, toProcess );
        }
        if ( !toProcess.isEmpty() && atLeastOneWasFound )
        {
            walkKnownBundleDependenciesUp( known, toProcess );
        }
    }

    //static and default for tests..
    static Map<String, Set<String>> computeClusterOrdering( Map<String, Set<String>> clusterDependencies, Map<String, Set<String>> clusterModules )
    {
        Map<String, Set<String>> cluster2depClusters = new HashMap<>();
        for ( Map.Entry<String, Set<String>> entry : clusterDependencies.entrySet() )
        {
            String cluster = entry.getKey();
            Set<String> deps = entry.getValue();
            for ( Map.Entry<String, Set<String>> subEnt : clusterModules.entrySet() )
            {
                if ( subEnt.getKey().equals( cluster ) )
                {
                    continue;
                }
                Sets.SetView<String> is = Sets.intersection( subEnt.getValue(), deps );
                if ( !is.isEmpty() )
                {
                    addToMap( cluster2depClusters, cluster, Collections.singletonList( subEnt.getKey() ) );
                }
            }
        }
        return cluster2depClusters;
    }
    
    static class BundleTuple
    {
        final Artifact artifact;
        final ExamineManifest manifest;
        String cluster;

        BundleTuple( Artifact artifact, ExamineManifest manifest )
        {
            this.artifact = artifact;
            this.manifest = manifest;
        }
        
    }

    private static class ClusterTuple
    {
        final File location;
        final boolean newer;

        private ClusterTuple( File clusterFile, boolean newer )
        {
            location = clusterFile;
            this.newer = newer;
        }
    }

    static String createBundleConfigFile( String cnb, boolean autoload )
    {
        return
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE module PUBLIC \"-//NetBeans//DTD Module Status 1.0//EN\"\n"
+ "                        \"http://www.netbeans.org/dtds/module-status-1_0.dtd\">\n"
+ "<module name=\"" + cnb + "\">\n"
+ "    <param name=\"autoload\">" + autoload + "</param>\n"
+ "    <param name=\"eager\">false</param>\n" + ( autoload ? "" : "    <param name=\"enabled\">true</param>\n" )
+ "    <param name=\"jar\">modules/" + cnb.replace( ".", "-" ) + ".jar</param>\n"
+ "    <param name=\"reloadable\">false</param>\n"
+ "</module>\n";
    }

    static String createBundleUpdateTracking( String cnb, File moduleArt, File moduleConf, String specVersion )
        throws FileNotFoundException, IOException
    {

        return
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<module codename=\"" + cnb + "\">\n"
+ "    <module_version install_time=\"" + System.currentTimeMillis() + "\" last=\"true\" origin=\"installer\" specification_version=\"" + specVersion + "\">\n"
+ "        <file crc=\"" + crcForFile( moduleConf ).getValue() + "\" name=\"config/Modules/" + cnb.replace( ".", "-" ) + ".xml\"/>\n"
+ "        <file crc=\"" + crcForFile( moduleArt ).getValue() + "\" name=\"modules/" + cnb.replace( ".", "-" ) + ".jar\"/>\n"
+ "    </module_version>\n"
+ "</module>";

    }

    static CRC32 crcForFile( File inFile )
        throws FileNotFoundException, IOException
    {
        CRC32 crc = new CRC32();
        try ( InputStream inFileStream = new FileInputStream( inFile ) )
        {
            byte[] array = new byte[(int) inFile.length()];
            int len = inFileStream.read( array );
            if ( len != array.length )
            {
                throw new IOException( "Cannot fully read " + inFile );
            }
            crc.update( array );
        }
        return crc;
    }

}
