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 java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.net.URL;
import java.text.BreakIterator;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Pattern;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactCollector;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
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.maven.shared.dependency.analyzer.DefaultClassAnalyzer;
import org.apache.maven.shared.dependency.analyzer.asm.ASMDependencyAnalyzer;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.shared.dependency.graph.DependencyNode;
import org.apache.netbeans.nbm.model.Dependency;
import org.apache.netbeans.nbm.model.NetBeansModule;
import org.apache.netbeans.nbm.utils.ExamineManifest;
import org.apache.tools.ant.taskdefs.Manifest;
import org.apache.tools.ant.taskdefs.ManifestException;
import org.codehaus.plexus.util.IOUtil;

/**
 * Goal for generating NetBeans module system specific manifest entries, part of <code>nbm</code> lifecycle/packaging.
 *
 * In order to have the generated manifest picked up by the maven-jar-plugin, one shall add the following configuration
 * snippet to maven-jar-plugin.
 *
 * <pre>
 *  {@code
 * <plugin>
 * <groupId>org.apache.maven.plugins</groupId>
 * <artifactId>maven-jar-plugin</artifactId>
 * <version>3.0.2</version>
 * <configuration>
 * <archive>
 * <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
 * </archive>
 * </configuration>
 * </plugin>
 * }
 * </pre>
 *
 * @author Milos Kleint
 */
@Mojo( name = "manifest",
        defaultPhase = LifecyclePhase.PROCESS_CLASSES,
        requiresProject = true,
        threadSafe = true,
        requiresDependencyResolution = ResolutionScope.RUNTIME )
public class NetBeansManifestUpdateMojo
        extends AbstractNbmMojo
{

    /**
     * NetBeans module assembly build directory. directory where the the NetBeans jar and nbm file get constructed.
     */
    @Parameter( defaultValue = "${project.build.directory}/nbm", property = "maven.nbm.buildDir" )
    protected File nbmBuildDir;

    /**
     * a NetBeans module descriptor containing dependency information and more
     *
     * @deprecated all content from the module descriptor can be defined as plugin configuration now, will be removed in
     * 4.0 entirely
     */
    @Parameter( defaultValue = "${basedir}/src/main/nbm/module.xml" )
    protected File descriptor;

    /**
     * maven project
     */
    @Parameter( required = true, readonly = true, property = "project" )
    private MavenProject project;

    /**
     * The location of JavaHelp sources for the project. The documentation itself is expected to be in the directory
     * structure based on codenamebase of the module. eg. if your codenamebase is "org.netbeans.modules.apisupport",
     * then the actual docs files shall go to ${basedir}/src/main/javahelp/org/netbeans/modules/apisupport/docs.
     * Obsolete as of NetBeans 7.0 with &#64;HelpSetRegistration.
     *
     * @since 2.7
     */
    @Parameter( defaultValue = "${basedir}/src/main/javahelp" )
    protected File nbmJavahelpSource;

    /**
     * Path to manifest file that will be used as base and enhanced with generated content. Any entry specified in the
     * original file will not be overwritten
     *
     * @since 3.0
     */
    @Parameter( required = true, defaultValue = "${basedir}/src/main/nbm/manifest.mf" )
    private File sourceManifestFile;

    /**
     * Path to the generated MANIFEST file to use. It will be used by jar:jar plugin.
     *
     * @since 3.0
     */
    @Parameter( required = true, readonly = true, defaultValue = "${project.build.outputDirectory}/META-INF/MANIFEST.MF" )
    private File targetManifestFile;

    /**
     * Verify the runtime NetBeans module dependencies and Class-Path items generated from Maven dependencies. The check
     * is done by matching classes used in current project. Allowed values for the parameter are <code>fail</code>,
     * <code>warn</code> and <code>skip</code>. The default is <code>fail</code> in which case the validation failure
     * results in a failed build, in the vast majority of cases the module would fail at runtime anyway.
     *
     * @since 3.0
     */
    @Parameter( property = "maven.nbm.verify", defaultValue = "fail" )
    private String verifyRuntime;

    private static final String FAIL = "fail";
    private static final String WARN = "warn";
    private static final String SKIP = "skip";

    /**
     * A list of module's public packages. If not defined, no packages are exported as public. Allowed values are single
     * package names or package names ending with .* which represent the package and all subpackages.
     * <p/>
     * Eg. "org.kleint.milos.api" designates just the one package, while "org.kleint.milos.spi.*" denotes the spi
     * package an all it's subpackages.
     *
     * @since 3.0
     */
    @Parameter
    private List<String> publicPackages;

    /**
     * When encountering an OSGi bundle among dependencies, the plugin will generate a direct dependency on the bundle
     * and will not include the bundle's jar into the nbm. Will only work with NetBeans 6.9+ runtime. Therefore it is
     * off by default. WARNING: Additionally existing applications/modules need to check modules wrapping external
     * libraries for library jars that are also OSGi bundles. Such modules will no longer include the OSGi bundles as
     * part of the module but will include a modular dependency on the bundle. Modules depending on these old wrappers
     * shall depend directly on the bundle, eventually rendering the old library wrapper module obsolete.
     *
     * @since 3.2
     */
    @Parameter( defaultValue = "false" )
    private boolean useOSGiDependencies;

    /**
     * codename base of the module, uniquely identifying the module within the NetBeans runtime. usually the package
     * name equivalent. Can include the major release version. See
     * <a href="http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#how-manifest">
     * NetBeans Module system docs</a>
     *
     * @since 3.8
     */
    @Parameter( defaultValue = "${project.groupId}.${project.artifactId}" )
    private String codeNameBase;

    /**
     * List of explicit module dependency declarations overriding the default specification dependency. Useful when
     * depending on a range of major versions, depending on implementation version etc.
     * <p>
     * The format is:
     * <pre>
     * &lt;dependency&gt;
     *    &lt;id&gt;groupId:artifactId&lt;/id&gt;
     *    &lt;type&gt;spec|impl|loose&lt;/type&gt;
     *    &lt;explicitValue&gt;the entire dependency token&lt;/explicitValue&gt;
     * &lt;/dependency&gt;
     * </pre>
     * </p>
     * <p>
     * where <code>id</code> is composed of grouId and artifactId of a dependency defined in effective pom, separated by
     * double colon. This is mandatory.</p>
     * <p>
     * Then there are 2 exclusively optional fields <code>type</code> and <code>explicitValue</code>, if both are
     * defined <code>explicitValue</code> gets applied.
     * </p>
     * <p>
     * <code>type</code> values: <code>spec</code> means specification dependency.That's the default. <code>impl</code>
     * means implementation dependency, only the exact version match will satisfy the constraint. <code>loose</code>
     * means loose dependency, no requirement on version, the module just has to be present. Not very common option.
     *
     * @since 3.8
     */
    @Parameter
    private Dependency[] moduleDependencies;

    /**
     * Deployment type of the module, allowed values are <code>normal</code>,<code>eager</code>,<code>autoload</code>,
     * <code>disabled</code>.
     * <p>
     * <code>autoload</code> - Such a module is automatically enabled when some other module requires it and
     * automatically disabled otherwise.</p>
     * <p>
     * <code>eager</code> - This module type gets automatically enabled when all it's dependencies are satisfied.
     * Disabled otherwise.</p>
     * <p>
     * <code>normal</code> - This is the default value. This kind of module is enabled/disabled manually by the user. It
     * installs enabled.</p>
     * <p>
     * <code>disabled</code> - This kind of module is enabled/disabled manually by the user. It installs disabled. Since
     * 3.11</p>
     *
     * For details, see
     * <a href="http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#enablement">Netbeans
     * Module system docs</a>
     *
     * Since 3.14, for autoload and eager modules, we automatically set AutoUpdate-Show-In-Client manifest entry to
     * false, if not defined already otherwise in the manifest. See issue
     * <a href="http://jira.codehaus.org/browse/MNBMODULE-194">MNBMODULE-194</a>
     *
     * @since 3.8 (3.14 in manifest goal)
     */
    @Parameter( defaultValue = "normal" )
    protected String moduleType;

    // <editor-fold defaultstate="collapsed" desc="Component parameters">
    /**
     * The artifact repository to use.
     *
     */
    @Parameter( required = true, readonly = true, defaultValue = "${localRepository}" )
    private ArtifactRepository localRepository;

    /**
     * The artifact factory to use.
     */
    @Component
    private ArtifactFactory artifactFactory;

    /**
     * The artifact metadata source to use.
     */
    @Component
    private ArtifactMetadataSource artifactMetadataSource;

    /**
     * The artifact collector to use.
     */
    @Component
    private ArtifactCollector artifactCollector;

    /**
     * The dependency tree builder to use.
     */
    @Component( hint = "default" )
    private DependencyGraphBuilder dependencyGraphBuilder;

// end of component params custom code folding
// </editor-fold> 
    /**
     * execute plugin
     *
     * @throws MojoExecutionException if an unexpected problem occurs
     * @throws MojoFailureException if an expected problem occurs
     */
    public void execute()
            throws MojoExecutionException, MojoFailureException

    {
        //need to do this to chekc for javahelp on CP.
        super.registerNbmAntTasks();
        NetBeansModule module;
        if ( descriptor != null && descriptor.exists() )
        {
            module = readModuleDescriptor( descriptor );
            getLog().warn( "descriptor parameter is deprecated, use equivalent mojo parameters instead." );
        }
        else
        {
            module = createDefaultDescriptor( project, false );
        }

        String mtype = moduleType;
        //same moduleType related code in CreateNetBeansFileStructure.java
        if ( "normal".equals( mtype ) && module.getModuleType() != null )
        {
            mtype = module.getModuleType();
            getLog().warn( "moduleType in module descriptor is deprecated, use the plugin's parameter moduleType" );
        }
        if ( !"normal".equals( mtype ) && !"autoload".equals( mtype ) && !"eager".equals( mtype ) && !"disabled".
                equals( mtype ) )
        {
            getLog().error( "Only 'normal,autoload,eager,disabled' are allowed values in the moduleType parameter" );
        }
        boolean autoload = "autoload".equals( mtype );
        boolean eager = "eager".equals( mtype );

        String moduleName = codeNameBase;
        if ( module.getCodeNameBase() != null )
        {
            moduleName = module.getCodeNameBase();
            getLog().warn( "codeNameBase in module descriptor is deprecated, use the plugin's parameter codeNameBase" );
        }
        moduleName = moduleName.replaceAll( "-", "." );
//<!-- if a NetBeans specific manifest is defined, examine this one, otherwise the already included one.
// ignoring the case when some of the NetBeans attributes are already defined in the jar and more is included.
        File specialManifest = sourceManifestFile;
        File nbmManifest = ( module.getManifest() != null ? new File(
                project.getBasedir(), module.getManifest() ) : null );
        if ( nbmManifest != null && nbmManifest.exists() )
        {
            //deprecated, but if actually defined, will use it.
            specialManifest = nbmManifest;
        }
        ExamineManifest examinator = new ExamineManifest( getLog() );
        if ( specialManifest != null && specialManifest.exists() )
        {
            examinator.setManifestFile( specialManifest );
            examinator.checkFile();
        }
        else
        {
//            examinator.setJarFile( jarFile );
        }

        getLog().info( "NBM Plugin generates manifest" );

        Manifest manifest = null;
        if ( specialManifest != null && specialManifest.exists() )
        {
            Reader reader = null;
            try
            {
                reader = new InputStreamReader( new FileInputStream( specialManifest ) );
                manifest = new Manifest( reader );
            }
            catch ( IOException exc )
            {
                manifest = new Manifest();
                getLog().warn( "Error reading manifest at " + specialManifest, exc );
            }
            catch ( ManifestException ex )
            {
                getLog().warn( "Error reading manifest at " + specialManifest, ex );
                manifest = new Manifest();
            }
            finally
            {
                IOUtil.close( reader );
            }
        }
        else
        {
            manifest = new Manifest();
        }
        Date date = new Date();
        String specVersion = AdaptNbVersion.adaptVersion( project.getVersion(),
                AdaptNbVersion.TYPE_SPECIFICATION, date );
        String implVersion = AdaptNbVersion.adaptVersion( project.getVersion(),
                AdaptNbVersion.TYPE_IMPLEMENTATION, date );
        Manifest.Section mainSection = manifest.getMainSection();
        conditionallyAddAttribute( mainSection,
                "OpenIDE-Module-Specification-Version", specVersion );
        conditionallyAddAttribute( mainSection,
                "OpenIDE-Module-Implementation-Version", implVersion );
        if ( autoload || eager )
        { //MNBMODULE-194
            conditionallyAddAttribute( mainSection, "AutoUpdate-Show-In-Client", "false" );
        }
        final String timestamp = createTimestamp( date );
        conditionallyAddAttribute( mainSection, "OpenIDE-Module-Build-Version",
                timestamp );
        String projectCNB = conditionallyAddAttribute( mainSection, "OpenIDE-Module", moduleName );
        String packagesValue;
        if ( publicPackages != null && publicPackages.size() > 0 )
        {
            StringBuilder sb = new StringBuilder();
            for ( String pub : publicPackages )
            {
                if ( pub == null )
                { //#MNBMODULE-237
                    continue;
                }
                if ( pub.endsWith( ".**" ) )
                {
                    // well, just sort of wrong value but accept
                    sb.append( pub );
                }
                else if ( pub.endsWith( ".*" ) )
                {
                    //multipackage value
                    sb.append( pub ).append( "*" );
                }
                else
                {
                    sb.append( pub ).append( ".*" );
                }
                sb.append( ", " );
            }
            if ( sb.length() > 1 )
            { //if only item is null, we have empty builder
                sb.setLength( sb.length() - 2 ); //cut the last 2 ", " characters
                packagesValue = sb.toString();
            }
            else
            {
                // no packages available
                packagesValue = "-";
            }
        }
        else
        {
            // no packages available
            packagesValue = "-";
        }
        conditionallyAddAttribute( mainSection, "OpenIDE-Module-Public-Packages", packagesValue );

        //See http://www.netbeans.org/download/dev/javadoc/org-openide-modules/apichanges.html#split-of-openide-jar
        conditionallyAddAttribute( mainSection, "OpenIDE-Module-Requires",
                "org.openide.modules.ModuleFormat1" );
//        conditionallyAddAttribute(mainSection, "OpenIDE-Module-IDE-Dependencies", "IDE/1 > 3.40");
        // localization items
        if ( !examinator.isLocalized() )
        {
            conditionallyAddAttribute( mainSection,
                    "OpenIDE-Module-Display-Category", project.getGroupId() );
            conditionallyAddAttribute( mainSection, "OpenIDE-Module-Name",
                    project.getName() );
            conditionallyAddAttribute( mainSection,
                    "OpenIDE-Module-Short-Description", shorten( project.getDescription() ) );
            conditionallyAddAttribute( mainSection,
                    "OpenIDE-Module-Long-Description", project.getDescription() );
        }
        getLog().debug( "module =" + module );

        DependencyNode treeroot = createDependencyTree( project, dependencyGraphBuilder, "compile" );
        Map<Artifact, ExamineManifest> examinerCache = new HashMap<Artifact, ExamineManifest>();
        @SuppressWarnings( "unchecked" )
        List<Artifact> libArtifacts = getLibraryArtifacts( treeroot, module, project.getRuntimeArtifacts(),
                examinerCache, getLog(), useOSGiDependencies );
        List<ModuleWrapper> moduleArtifacts = getModuleDependencyArtifacts( treeroot, module, moduleDependencies,
                project, examinerCache,
                libArtifacts, getLog(), useOSGiDependencies );
        StringBuilder classPath = new StringBuilder();
        StringBuilder mavenClassPath = new StringBuilder();
        String dependencies = "";
        String depSeparator = " ";

        for ( Artifact a : libArtifacts )
        {
            if ( classPath.length() > 0 )
            {
                classPath.append( ' ' );
            }
            classPath.append( artifactToClassPathEntry( a, codeNameBase ) );
            if ( mavenClassPath.length() > 0 )
            {
                mavenClassPath.append( ' ' );
            }
            mavenClassPath.append( a.getGroupId() ).
                    append( ':' ).
                    append( a.getArtifactId() ).
                    append( ':' ).
                    append( a.getBaseVersion() );

            if ( a.getClassifier() != null )
            {
                mavenClassPath.append( ":" ).append( a.getClassifier() );
            }
        }

        for ( ModuleWrapper wr : moduleArtifacts )
        {
            if ( wr.transitive )
            {
                continue;
            }
            Dependency dep = wr.dependency;
            Artifact artifact = wr.artifact;
            ExamineManifest depExaminator = examinerCache.get( artifact );
            String type = dep.getType();
            String depToken = dep.getExplicitValue();
            if ( depToken == null )
            {
                if ( "loose".equals( type ) )
                {
                    depToken = depExaminator.getModuleWithRelease();
                }
                else if ( "spec".equals( type ) )
                {
                    depToken
                            = depExaminator.getModuleWithRelease()
                            + " > "
                            + ( depExaminator.isNetBeansModule() ? depExaminator.getSpecVersion()
                            : AdaptNbVersion.adaptVersion( depExaminator.getSpecVersion(),
                                    AdaptNbVersion.TYPE_SPECIFICATION, date ) );
                }
                else if ( "impl".equals( type ) )
                {
                    depToken
                            = depExaminator.getModuleWithRelease()
                            + " = "
                            + ( depExaminator.isNetBeansModule() ? depExaminator.getImplVersion()
                            : AdaptNbVersion.adaptVersion( depExaminator.getImplVersion(),
                                    AdaptNbVersion.TYPE_IMPLEMENTATION, date ) );
                }
                else
                {
                    throw new MojoExecutionException(
                            "Wrong type of NetBeans dependency: " + type + " Allowed values are: loose, spec, impl." );
                }
            }
            if ( depToken == null )
            {
                //TODO report
                getLog().error(
                        "Cannot properly resolve the NetBeans dependency for " + dep.getId() );
            }
            else
            {
                dependencies = dependencies + depSeparator + depToken;
                depSeparator = ", ";
            }
        }
        if ( !verifyRuntime.equalsIgnoreCase( SKIP ) )
        {
            try
            {
                checkModuleClassPath( treeroot, libArtifacts, examinerCache, moduleArtifacts, projectCNB );
            }
            catch ( IOException ex )
            {
                throw new MojoExecutionException( "Error while checking runtime dependencies", ex );
            }
        }

        if ( nbmJavahelpSource.exists() )
        {
            String moduleJarName = stripVersionFromCodebaseName( moduleName ).replace( ".", "-" );
            classPath.append( " docs/" ).append( moduleJarName ).append( ".jar" );
        }

        if ( classPath.length() > 0 )
        {
            conditionallyAddAttribute( mainSection, "X-Class-Path", classPath.toString().trim() );
        }
        if ( mavenClassPath.length() > 0 )
        {
            conditionallyAddAttribute( mainSection, "Maven-Class-Path", mavenClassPath.toString() );
        }
        if ( dependencies.length() > 0 )
        {
            conditionallyAddAttribute( mainSection, "OpenIDE-Module-Module-Dependencies", dependencies );
        }
//            if ( librList.size() > 0 )
//            {
//                String list = "";
//                for ( int i = 0; i < librList.size(); i++ )
//                {
//                    list = list + " " + librList.get( i );
//                }
//                getLog().warn(
//                        "Some libraries could not be found in the dependency chain: " + list );
//            }
        PrintWriter writer = null;
        try
        {
            if ( !targetManifestFile.exists() )
            {
                targetManifestFile.getParentFile().mkdirs();
                targetManifestFile.createNewFile();
            }
            writer = new PrintWriter( targetManifestFile, "UTF-8" ); //TODO really UTF-8??
            manifest.write( writer );
        }
        catch ( IOException ex )
        {
            throw new MojoExecutionException( ex.getMessage(), ex );
        }
        finally
        {
            IOUtil.close( writer );
        }
    }

    //MNBMODULE-137
    static String artifactToClassPathEntry( Artifact a, String codenamebase )
    {
        return "ext/" + codenamebase + "/" + a.getGroupId().replace( '.', '-' ) + "/" + a.getArtifactId() + ( a.
                getClassifier() != null ? "-" + a.getClassifier() : "" ) + "." + a.getArtifactHandler().getExtension();
    }

    /**
     * Create a timestamp for <code>OpenIDE-Module-Build-Version</code> manifest entry.
     *
     * It's created from the current time and formatted using a UTC timezone explicitly which makes created timestamp
     * timezone-independent.
     *
     * @return timestamp represented as <code>201012292045</code>
     */
    private static String createTimestamp( Date date )
    {
        final SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyyMMddHHmm" );
        dateFormat.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
        final String timestamp = dateFormat.format( date );
        return timestamp;
    }

    static String stripVersionFromCodebaseName( String cnb )
    {
        // it can happen the moduleName is in format org.milos/1
        String base = cnb;
        int index = base.indexOf( '/' );
        if ( index > -1 )
        {
            base = base.substring( 0, index ).trim();
        }
        return base;
    }

    String conditionallyAddAttribute( Manifest.Section section, String key, String value )
    {
        Manifest.Attribute attr = section.getAttribute( key );
        if ( attr == null )
        {
            attr = new Manifest.Attribute();
            attr.setName( key );
            attr.setValue( value != null ? value.replaceAll( "\\s+", " " ).trim() : "<undefined>" );
            try
            {
                section.addConfiguredAttribute( attr );
            }
            catch ( ManifestException ex )
            {
                getLog().error( "Cannot update manifest (key=" + key + ")" );
                ex.printStackTrace();
            }
        }
        return attr.getValue();
    }

    /**
     * Pick out the first sentence of a paragraph.
     *
     * @param paragraph some text (may be null)
     * @return the first sentence (may be null)
     */
    static String shorten( String paragraph )
    {
        if ( paragraph == null || paragraph.length() == 0 )
        {
            return null;
        }
        BreakIterator breaker = BreakIterator.getSentenceInstance();
        breaker.setText( paragraph );
        return paragraph.substring( 0, breaker.following( 0 ) ).trim();
    }

//----------------------------------------------------------------------------------
// classpat checking related.
//----------------------------------------------------------------------------------
    private void checkModuleClassPath( DependencyNode treeroot,
            List<Artifact> libArtifacts,
            Map<Artifact, ExamineManifest> examinerCache, List<ModuleWrapper> moduleArtifacts,
            String projectCodeNameBase )
            throws IOException, MojoExecutionException, MojoFailureException
    {
        Set<String> deps = buildProjectDependencyClasses( project, libArtifacts );
        deps.retainAll( allProjectClasses( project ) );

        Set<String> own = projectModuleOwnClasses( project, libArtifacts );
        deps.removeAll( own );
        CollectModuleLibrariesNodeVisitor visitor = new CollectModuleLibrariesNodeVisitor(
                project.getRuntimeArtifacts(), examinerCache, getLog(), treeroot, useOSGiDependencies );
        treeroot.accept( visitor );
        Map<String, List<Artifact>> modules = visitor.getDeclaredArtifacts();
        Map<Artifact, Set<String>> moduleAllClasses = new HashMap<Artifact, Set<String>>();

        for ( ModuleWrapper wr : moduleArtifacts )
        {
            if ( modules.containsKey( wr.artifact.getDependencyConflictId() ) )
            {
                ExamineManifest man = examinerCache.get( wr.artifact );
                List<Artifact> arts = modules.get( wr.artifact.getDependencyConflictId() );
                Set<String>[] classes = visibleModuleClasses( arts, man, wr.dependency, projectCodeNameBase, false );
                deps.removeAll( classes[0] );
                moduleAllClasses.put( wr.artifact, classes[1] );
            }
        }

        //now we have the classes that are not in public packages of declared modules,
        //but are being used
        if ( !deps.isEmpty() )
        {
            Map<String, List<Artifact>> transmodules = visitor.getTransitiveArtifacts();
            for ( ModuleWrapper wr : moduleArtifacts )
            {
                if ( transmodules.containsKey( wr.artifact.getDependencyConflictId() ) )
                {
                    ExamineManifest man = examinerCache.get( wr.artifact );
                    List<Artifact> arts = transmodules.get( wr.artifact.getDependencyConflictId() );
                    Set<String>[] classes = visibleModuleClasses( arts, man, wr.dependency, projectCodeNameBase, true );
                    classes[0].retainAll( deps );
                    if ( classes[0].size() > 0 )
                    {
                        String module = wr.osgi ? "OSGi bundle" : "module";
                        getLog().error(
                                "Project uses classes from transitive " + module + " " + wr.artifact.getId()
                                + " which will not be accessible at runtime." );
                        getLog().info(
                                "    To fix the problem, add this module as direct dependency. For OSGi bundles that are supposed to be wrapped in NetBeans modules, use the useOSGiDependencies=false parameter" );
                        deps.removeAll( classes[0] );
                    }
                    classes[1].retainAll( deps );
                    if ( classes[1].size() > 0 )
                    {
                        getLog().info( "Private classes referenced in transitive module: " + Arrays.toString(
                                classes[1].toArray() ) );
                        getLog().error(
                                "Project depends on packages not accessible at runtime in transitive module "
                                + wr.artifact.getId() + " which will not be accessible at runtime." );
                        deps.removeAll( classes[1] );
                    }
                }
            }
            for ( Map.Entry<Artifact, Set<String>> e : moduleAllClasses.entrySet() )
            {
                List<String> strs = new ArrayList<String>( deps );
                if ( deps.removeAll( e.getValue() ) )
                {
                    strs.retainAll( e.getValue() );
                    getLog().info( "Private classes referenced in module: " + Arrays.toString( strs.toArray() ) );
                    getLog().error( "Project depends on packages not accessible at runtime in module " + e.getKey().
                            getId() );
                }
            }
            if ( verifyRuntime.equalsIgnoreCase( FAIL ) )
            {
                if ( !deps.isEmpty() )
                {
                    throw new MojoFailureException(
                            "Uncategorized problems with NetBeans dependency verification (maybe MNBMODULE-102 or wrong maven dependency metadata). Supposedly external classes are used in the project's binaries but the classes are not found on classpath. Class usages: "
                            + deps );
                }
                else
                {
                    throw new MojoFailureException(
                            "See above for failures in runtime NetBeans dependencies verification." );
                }
            }
        }
    }

    /**
     * The current projects's dependencies, includes classes used in teh module itself and the classpath libraries as
     * well.
     *
     * @param project
     * @param libraries
     * @return
     * @throws java.io.IOException
     */
    private Set<String> buildProjectDependencyClasses( MavenProject project, List<Artifact> libraries )
            throws IOException
    {
        Set<String> dependencyClasses = new HashSet<String>();

        String outputDirectory = project.getBuild().getOutputDirectory();
        dependencyClasses.addAll( buildDependencyClasses( outputDirectory ) );

        for ( Artifact lib : libraries )
        {
            dependencyClasses.addAll( buildDependencyClasses( lib.getFile().getAbsolutePath() ) );
        }
        return dependencyClasses;
    }

    @SuppressWarnings( "unchecked" )
    private Set<String> projectModuleOwnClasses( MavenProject project, List<Artifact> libraries )
            throws IOException
    {
        Set<String> projectClasses = new HashSet<String>();
        DefaultClassAnalyzer analyzer = new DefaultClassAnalyzer();

        String outputDirectory = project.getBuild().getOutputDirectory();
        URL fl = new File( outputDirectory ).toURI().toURL();
        projectClasses.addAll( analyzer.analyze( fl ) );

        for ( Artifact lib : libraries )
        {
            URL url = lib.getFile().toURI().toURL();
            projectClasses.addAll( analyzer.analyze( url ) );
        }

        return projectClasses;
    }

    /**
     * complete list of classes on project runtime classpath (excluding jdk bit)
     *
     * @param project
     * @return
     * @throws java.io.IOException
     */
    @SuppressWarnings( "unchecked" )
    private Set<String> allProjectClasses( MavenProject project )
            throws IOException
    {
        Set<String> projectClasses = new HashSet<String>();
        DefaultClassAnalyzer analyzer = new DefaultClassAnalyzer();

        String outputDirectory = project.getBuild().getOutputDirectory();
        URL fl = new File( outputDirectory ).toURI().toURL();
        projectClasses.addAll( analyzer.analyze( fl ) );

        List<Artifact> libs = project.getRuntimeArtifacts();

        for ( Artifact lib : libs )
        {
            URL url = lib.getFile().toURI().toURL();
            projectClasses.addAll( analyzer.analyze( url ) );
        }

        return projectClasses;
    }

    private Set<String>[] visibleModuleClasses( List<Artifact> moduleLibraries,
            ExamineManifest manifest, Dependency dep, String projectCodeNameBase,
            boolean transitive )
            throws IOException, MojoFailureException
    {
        Set<String> moduleClasses = new HashSet<String>();
        Set<String> visibleModuleClasses = new HashSet<String>();
        DefaultClassAnalyzer analyzer = new DefaultClassAnalyzer();
        String type = dep.getType();
        if ( dep.getExplicitValue() != null )
        {
            if ( dep.getExplicitValue().contains( "=" ) )
            {
                type = "impl";
            }
        }
        if ( type == null || "loose".equals( type ) )
        {
            type = "spec";
        }

        for ( Artifact lib : moduleLibraries )
        {
            URL url = lib.getFile().toURI().toURL();
            moduleClasses.addAll( analyzer.analyze( url ) );
        }

        if ( "spec".equals( type ) )
        {
            String cnb = stripVersionFromCodebaseName( projectCodeNameBase );
            if ( !transitive && manifest.hasFriendPackages() && !manifest.getFriends().contains( cnb ) )
            {
                String message = "Module has friend dependency on " + manifest.getModule()
                        + " but is not listed as a friend.";
                if ( verifyRuntime.equalsIgnoreCase( FAIL ) )
                {
                    throw new MojoFailureException( message );
                }
                else
                {
                    getLog().warn( message );
                }
            }
            List<Pattern> compiled = createCompiledPatternList( manifest.getPackages() );
            if ( useOSGiDependencies && manifest.isOsgiBundle() )
            {
                // TODO how to extract the public packages in osgi bundles easily..
                compiled = Collections.singletonList( Pattern.compile( "(.+)" ) );
            }
            for ( String clazz : moduleClasses )
            {
                for ( Pattern patt : compiled )
                {
                    if ( patt.matcher( clazz ).matches() )
                    {
                        visibleModuleClasses.add( clazz );
                        break;
                    }
                }
            }

        }
        else if ( "impl".equals( type ) )
        {
            visibleModuleClasses.addAll( moduleClasses );
        }
        else
        {
            //HUH?
            throw new MojoFailureException( "Wrong type of module dependency " + type );
        }

        return new Set[]
        {
            visibleModuleClasses,
            moduleClasses
        };
    }

    static List<Pattern> createCompiledPatternList( List<String> packages )
    {
        List<Pattern> toRet = new ArrayList<Pattern>();
        for ( String token : packages )
        {
            if ( token.endsWith( ".**" ) )
            {
                String patt = "^" + Pattern.quote( token.substring( 0, token.length() - 2 ) ) + "(.+)";
                toRet.add( 0, Pattern.compile( patt ) );
            }
            else
            {
                String patt = "^" + Pattern.quote( token.substring( 0, token.length() - 1 ) ) + "([^\\.]+)";
                toRet.add( Pattern.compile( patt ) );
            }
        }
        return toRet;
    }

    @SuppressWarnings( "unchecked" )
    private Set<String> buildDependencyClasses( String path )
            throws IOException
    {
        URL url = new File( path ).toURI().toURL();
        ASMDependencyAnalyzer dependencyAnalyzer = new ASMDependencyAnalyzer();
        return dependencyAnalyzer.analyze( url );
    }
}
