/* ==========================================================================
 * Copyright Milos Kleint
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * =========================================================================
 */
package org.netbeans.nbm;

import com.google.common.collect.Sets;
import java.io.*;
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.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 <a href="mailto:mkleint@codehaus.org">Milos Kleint</a>
 */
@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;
    
    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()) {
                                                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 final static 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:m2:/" ) )
            {
                if ( ! found )
                {
                    String[] coords = line.substring( 8 ).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 ( line.startsWith( "URL:" ) )
            {
                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 ("org.netbeans.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(
            "org.netbeans.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;
    }

}
