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<>( SET_INITIAL_SIZE );
            Set<String> dependencyCNBs = new HashSet<>( SET_INITIAL_SIZE );
            Map<String, Set<String>> dependencyCNBBacktraces = new HashMap<>( MAP_INITIALSIZE );
            Set<String> requireTokens = new HashSet<>( MAP_INITIALSIZE );
            Map<String, Set<String>> requireTokensBacktraces = new HashMap<>( MAP_INITIALSIZE );
            Set<String> provideTokens = new HashSet<>( MAP_INITIALSIZE );
            Set<String> osgiImports = new HashSet<>( MAP_INITIALSIZE );
            Map<String, Set<String>> osgiImportsBacktraces = new HashMap<>( MAP_INITIALSIZE );
            Set<String> osgiExports = new HashSet<>( MAP_INITIALSIZE );
            Set<String> osgiExportsSubs = new HashSet<>( MAP_INITIALSIZE ); //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 int SET_INITIAL_SIZE = 200;
    private static final int MAP_INITIALSIZE = 50;
    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 );

        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 );
            }
        }

        if ( binDirectory != null )
        {
            //we have custom launchers, only overwrite the ones the user provided.
            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
                }
            }
        }

        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;
    }

}
