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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
//import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Resource;
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.Parameter;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.filtering.MavenResourcesExecution;
import org.apache.maven.shared.filtering.MavenResourcesFiltering;
import org.apache.netbeans.nbm.model.NbmResource;
import org.apache.netbeans.nbm.model.NetBeansModule;
import org.apache.netbeans.nbm.utils.ExamineManifest;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.taskdefs.Jar;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PatternSet;
import org.apache.tools.ant.util.FileUtils;
import org.netbeans.nbbuild.CreateModuleXML;
import org.netbeans.nbbuild.MakeListOfNBM;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.netbeans.nbbuild.JHIndexer;

/**
 * Create the NetBeans module directory structure, a prerequisite for nbm creation and cluster creation.
 * 
 *
 * @author Milos Kleint
 *
 */
public abstract class CreateNetBeansFileStructure
        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;
    /**
     * Build directory
     */
    @Parameter( required = true, readonly = true, property = "project.build.directory" )
    protected File buildDir;
    /**
     * Name of the jar packaged by the jar:jar plugin
     */
    @Parameter( alias = "jarname", property = "project.build.finalName" )
    protected String finalName;
    /**
     * 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;
    /**
     * NetBeans module's cluster. Replaces the cluster element in module descriptor.
     *
     */
    @Parameter( required = true, defaultValue = "extra" )
    protected String cluster;
    /**
     * 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.
     * @deprecated Obsolete as of NetBeans 7.0 with &#64;HelpSetRegistration.
     * @since 2.7
     */
    @Deprecated
    @Parameter( defaultValue = "${basedir}/src/main/javahelp" )
    protected File nbmJavahelpSource;

    @Parameter( required = true, readonly = true, property = "project" )
    protected MavenProject project;

    /**
     * A list of additional resources to include in the NBM file.
     * (Not in the module JAR; see <code>InstalledFileLocator</code> for retrieval.)
     * Supersedes similarly-named configuration in the module descriptor file.
     * <p>For example, to include native libraries:</p>
     *
     <pre>
            &lt;nbmResource&gt;
            &nbsp;&nbsp;&lt;directory&gt;src/main/libs&lt;/directory&gt;
            &nbsp;&nbsp;&lt;targetPath&gt;modules/lib&lt;/targetPath&gt;
            &nbsp;&nbsp;&lt;includes&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&lt;include&gt;*.dll&lt;/include&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&lt;include&gt;*.so&lt;/include&gt;
            &nbsp;&nbsp;&lt;/includes&gt;
            &lt;/nbmResource&gt;
     </pre>
     *
     * @since 3.2
     */
    @Parameter
    protected Resource[] nbmResources;

    /**
     * The character encoding scheme to be applied when filtering nbm resources.
     *
     * @since 3.2
     */
    @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
    
    protected String encoding;
    
    /**
     * 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
     */ 
    @Parameter( defaultValue = "normal" )
    protected String moduleType;
    
    /**
     * 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 groupId:artifactId pairs describing libraries that go into the nbm file and will only include the .external reference in the nbm
     * instead of the actual binary. See <a href="http://netbeans.org/bugzilla/show_bug.cgi?id=195041">NetBeans issue #195041</a> for details.
     * Please note that the scheme will only work for artifacts present in central repository but no effort is made at build time to enforce that.
     * Additionally at runtime when installing the module, the user has to be online and be capable of reaching central using maven. 
     * You have been warned.
     * @since 3.8
     */ 
    @Parameter
    private List<String> externals;


    @Component
    protected MavenResourcesFiltering mavenResourcesFiltering;

    @Parameter( property = "session", readonly = true, required = true )
    protected MavenSession session;


    //items used by the CreateNBMMojo.
    protected Project antProject;
    protected NetBeansModule module;
    protected File clusterDir;
    protected String moduleJarName;

    @Override
    public void execute()
            throws MojoExecutionException, MojoFailureException
    {
        antProject = registerNbmAntTasks();
        if ( descriptor != null && descriptor.exists() )
        {
            module = readModuleDescriptor( descriptor );
        }
        else
        {
            module = createDefaultDescriptor( project, false );
        }
        //same moduleType related code in NetBeansManifestUpdateMojo.java
        String type = moduleType;
        if ( "normal".equals( type ) && module.getModuleType() != null )
        {
            type = module.getModuleType();
            getLog().warn( "moduleType in module descriptor is deprecated, use the plugin's parameter moduleType" );
        }
        if ( !"normal".equals( type ) && !"autoload".equals( type ) && !"eager".equals( type ) && !"disabled".equals( type ) )
        {
            getLog().error( "Only 'normal,autoload,eager,disabled' are allowed values in the moduleType parameter" );
        }
        boolean autoload = "autoload".equals( type );
        boolean eager = "eager".equals( type );
        boolean disabled = "disabled".equals( type );
        // 1. initialization
        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 = NetBeansManifestUpdateMojo.stripVersionFromCodebaseName( moduleName.replaceAll( "-", "." ) );
        moduleJarName = moduleName.replace( '.', '-' );
        if ( "extra".equals( cluster ) && module.getCluster() != null )
        {
            getLog().warn(
                    "Parameter cluster in module descriptor is deprecated, use the plugin configuration element." );
            cluster = module.getCluster();
        }
        File jarFile = new File( buildDir, finalName + ".jar" );
        clusterDir = new File( nbmBuildDir, "netbeans" + File.separator + cluster );
        File moduleJarLocation = new File( clusterDir, "modules" );
        moduleJarLocation.mkdirs();

        //2. create nbm resources
        File moduleFile = new File( moduleJarLocation, moduleJarName + ".jar" );

        try
        {
            boolean needPlainCopy = false;
            InputStream is = new FileInputStream( jarFile );
            try
            {
                JarInputStream jis = new JarInputStream( is );
                Manifest m = jis.getManifest();
                Attributes a = m.getMainAttributes();
                String classPath = ( String ) a.remove( new Attributes.Name( "X-Class-Path" ) );
                if ( classPath == null )
                {
                    needPlainCopy = true;
                }
                else // MNBMODULE-133
                {
                    getLog().info( "Copying module JAR to " + moduleJarLocation + " with manifest updates" );
                    a.putValue( "Class-Path", classPath );
                    a.remove( new Attributes.Name( "Maven-Class-Path" ) );
                    OutputStream os = new FileOutputStream( moduleFile );
                    try
                    {
                        JarOutputStream jos = new JarOutputStream( os, m );
                        JarEntry entry;
                        while ( ( entry = jis.getNextJarEntry() ) != null )
                        {
                            JarEntry entry2 = new JarEntry( entry );
                            jos.putNextEntry( entry2 );
                            int c;
                            while ( ( c = jis.read() ) != -1 )
                            {
                                jos.write( c );
                            }
                            jos.closeEntry();
                        }
                        jos.finish();
                        jos.close();
                    }
                    finally
                    {
                        os.close();
                    }
                }
            }
            finally
            {
                is.close();
            }
            if ( needPlainCopy )
            {
                getLog().info( "Copying module JAR to " + moduleJarLocation );
                FileUtils.getFileUtils().copyFile( jarFile, moduleFile, null, true, false );
            }
        }
        catch ( IOException x )
        {
            throw new MojoExecutionException( "Cannot copy module jar", x );
        }

        ExamineManifest modExaminator = new ExamineManifest( getLog() );
        modExaminator.setJarFile( moduleFile );
        modExaminator.checkFile();
        String classpathValue = modExaminator.getClasspath();

        if ( module != null )
        {
            // copy libraries to the designated place..
            @SuppressWarnings( "unchecked" )
            List<Artifact> artifacts = project.getRuntimeArtifacts();
            for ( Artifact artifact : artifacts )
            {
                File source = artifact.getFile();
                
                String path = NetBeansManifestUpdateMojo.artifactToClassPathEntry( artifact, codeNameBase );
                
                if ( classpathValue.contains( path ) )
                {
                    File target = new File( moduleJarLocation, path );

                    File targetDir = target.getParentFile();
                    targetDir.mkdirs();

                    try
                    {
                        FileUtils.getFileUtils().copyFile( source, target, null, true, false );
                        if ( externals != null && externals.contains( artifact.getGroupId() + ":" + artifact.getArtifactId() ) ) // MNBMODULE-138
                        {
                            String name = target.getName();
                            getLog().info( "Using *.external replacement for " + name );
                            PrintWriter external = new PrintWriter( new File( targetDir, name + ".external" ), "UTF-8" );
                            try
                            {
                                writeExternal( external, artifact );
                            }
                            finally
                            {
                                external.close();
                            }
                        }
                    }
                    catch ( IOException ex )
                    {
                        getLog().error( "Cannot copy library jar" );
                        throw new MojoExecutionException( "Cannot copy library jar", ex );
                    }
                }
            }
            if ( nbmResources != null )
            {
                copyNbmResources();
            }
            copyDeprecatedNbmResources();
        }

        //javahelp stuff.
        if ( nbmJavahelpSource.exists() )
        {
            getLog().warn( "src/main/javahelp/ deprecated; use @HelpSetRegistration instead" );
            File javahelpTarget = new File( buildDir, "javahelp" );
            String javahelpbase = moduleJarName.replace( '-', File.separatorChar ) + File.separator + "docs";
            String javahelpSearch = "JavaHelpSearch";
            File b = new File( javahelpTarget, javahelpbase );
            File p = new File( b, javahelpSearch );
            p.mkdirs();
            Copy cp = (Copy) antProject.createTask( "copy" );
            cp.setTodir( javahelpTarget );
            FileSet set = new FileSet();
            set.setDir( nbmJavahelpSource );
            cp.addFileset( set );
            cp.execute();
            getLog().info( "Generating JavaHelp Index..." );

            JHIndexer jhTask = (JHIndexer) antProject.createTask( "jhindexer" );
            jhTask.setBasedir( b );
            jhTask.setDb( p );
            jhTask.setIncludes( "**/*.html" );
            jhTask.setExcludes( javahelpSearch );
            Path path = new Path( antProject );
            jhTask.setClassPath( path );
            clearStaticFieldsInJavaHelpIndexer();
            try
            {
                jhTask.execute();
            }
            catch ( BuildException e )
            {
                getLog().error( "Cannot generate JavaHelp index." );
                throw new MojoExecutionException( e.getMessage(), e );
            }
            File helpJarLocation = new File( clusterDir, "modules/docs" );
            helpJarLocation.mkdirs();
            Jar jar = (Jar) antProject.createTask( "jar" );
            jar.setDestFile( new File( helpJarLocation, moduleJarName + ".jar" ) );
            set = new FileSet();
            set.setDir( javahelpTarget );
            jar.addFileset( set );
            jar.execute();
        }

        File configDir = new File( clusterDir, "config" + File.separator + "Modules" );
        configDir.mkdirs();
        CreateModuleXML moduleXmlTask = (CreateModuleXML) antProject.createTask( "createmodulexml" );
        moduleXmlTask.setXmldir( configDir );
        FileSet fs = new FileSet();
        fs.setDir( clusterDir );
        fs.setIncludes( "modules" + File.separator + moduleJarName + ".jar" );
        if ( autoload )
        {
            moduleXmlTask.addAutoload( fs );
        }
        else if ( eager )
        {
            moduleXmlTask.addEager( fs );
        }
        else if ( disabled )
        {
            moduleXmlTask.addDisabled( fs );
        }
        else
        {
            moduleXmlTask.addEnabled( fs );
        }
        try
        {
            moduleXmlTask.execute();
        }
        catch ( BuildException e )
        {
            getLog().error( "Cannot generate config file." );
            throw new MojoExecutionException( e.getMessage(), e );
        }
        MakeListOfNBM makeTask = (MakeListOfNBM) antProject.createTask( "genlist" );
        antProject.setNewProperty( "module.name", finalName );
        antProject.setProperty( "cluster.dir", cluster );
        FileSet set = makeTask.createFileSet();
        set.setDir( clusterDir );
        PatternSet pattern = set.createPatternSet();
        pattern.setIncludes( "**" );
        makeTask.setModule( "modules" + File.separator + moduleJarName + ".jar" );
        makeTask.setOutputfiledir( clusterDir );
        try
        {
            makeTask.execute();
        }
        catch ( BuildException e )
        {
            getLog().error( "Cannot Generate nbm list" );
            throw new MojoExecutionException( e.getMessage(), e );
        }

    }

    private void copyDeprecatedNbmResources()
        throws BuildException, MojoExecutionException
    {
        // copy additional resources..
        List<NbmResource> ress = module.getNbmResources();
        if ( ress.size() > 0 )
        {
            getLog().warn( "NBM resources defined in module descriptor are deprecated. Please configure NBM resources in plugin configuration." );
            Copy cp = (Copy) antProject.createTask( "copy" );
            cp.setTodir( clusterDir );
            HashMap<File, Collection<FileSet>> customPaths = new HashMap<File, Collection<FileSet>>();
            boolean hasStandard = false;
            for ( NbmResource res : ress )
            {
                if ( res.getBaseDirectory() != null )
                {
                    File base = new File( project.getBasedir(), res.getBaseDirectory() );
                    FileSet set = new FileSet();
                    set.setDir( base );
                    for ( String inc : res.getIncludes() )
                    {
                        set.createInclude().setName( inc );
                    }
                    for ( String exc : res.getExcludes() )
                    {
                        set.createExclude().setName( exc );
                    }

                    if ( res.getRelativeClusterPath() != null )
                    {
                        File path = new File( clusterDir, res.getRelativeClusterPath() );
                        Collection<FileSet> col = customPaths.get( path );
                        if ( col == null )
                        {
                            col = new ArrayList<FileSet>();
                            customPaths.put( path, col );
                        }
                        col.add( set );
                    }
                    else
                    {
                        cp.addFileset( set );
                        hasStandard = true;
                    }
                }
            }
            try
            {
                if ( hasStandard )
                {
                    cp.execute();
                }
                if ( customPaths.size() > 0 )
                {
                    for ( Map.Entry<File, Collection<FileSet>> ent : customPaths.entrySet() )
                    {
                        cp = (Copy) antProject.createTask( "copy" );
                        cp.setTodir( ent.getKey() );
                        for ( FileSet set : ent.getValue() )
                        {
                            cp.addFileset( set );
                        }
                        cp.execute();
                    }
                }
            }
            catch ( BuildException e )
            {
                getLog().error( "Cannot copy additional resources into the nbm file" );
                throw new MojoExecutionException( e.getMessage(), e );
            }
        }
    }

    // repeated invokation of the javahelp indexer (possibly via multiple classloaders)
    // is causing trouble, residue from previous invokations seems to cause errors
    // this is a nasty workaround for the problem.
    // alternatively we could try invoking the indexer from a separate jvm i guess,
    // ut that's more work.
    private void clearStaticFieldsInJavaHelpIndexer() // MNBMODULE-51 hack
    {
        try
        {
            Class clazz = Class.forName( "com.sun.java.help.search.Indexer" );
            Field fld = clazz.getDeclaredField( "kitRegistry" );
            fld.setAccessible( true );
            Hashtable hash = (Hashtable) fld.get( null );
            hash.clear();

            clazz = Class.forName( "com.sun.java.help.search.HTMLIndexerKit" );
            fld = clazz.getDeclaredField( "defaultParser" );
            fld.setAccessible( true );
            fld.set( null, null );

            fld = clazz.getDeclaredField( "defaultCallback" );
            fld.setAccessible( true );
            fld.set( null, null );

        }
        catch ( IllegalArgumentException ex )
        {
            Logger.getLogger( CreateNetBeansFileStructure.class.getName() ).log( Level.SEVERE, null, ex );
        }
        catch ( IllegalAccessException ex )
        {
            Logger.getLogger( CreateNetBeansFileStructure.class.getName() ).log( Level.SEVERE, null, ex );
        }
        catch ( NoSuchFieldException ex )
        {
            Logger.getLogger( CreateNetBeansFileStructure.class.getName() ).log( Level.SEVERE, null, ex );
        }
        catch ( SecurityException ex )
        {
            Logger.getLogger( CreateNetBeansFileStructure.class.getName() ).log( Level.SEVERE, null, ex );
        }
        catch ( ClassNotFoundException ex )
        {
            Logger.getLogger( CreateNetBeansFileStructure.class.getName() ).log( Level.SEVERE, null, ex );
        }
    }

    private void copyNbmResources()
        throws MojoExecutionException
    {
        try
        {
            if ( StringUtils.isEmpty( encoding ) && isFilteringEnabled( nbmResources ) )
            {
                getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
                                   + ", i.e. build is platform dependent!" );
            }
            MavenResourcesExecution mavenResourcesExecution =
                new MavenResourcesExecution( Arrays.asList( nbmResources ), clusterDir, project, encoding,
                                             Collections.EMPTY_LIST, Collections.EMPTY_LIST, session );
            mavenResourcesExecution.setEscapeWindowsPaths( true );
            mavenResourcesFiltering.filterResources( mavenResourcesExecution );
        }
        catch ( MavenFilteringException ex )
        {
            throw new MojoExecutionException( ex.getMessage(), ex );
        }
    }

    /**
     * Determines whether filtering has been enabled for any resource.
     *
     * @param resources The set of resources to check for filtering.
     * @return <code>true</code> if at least one resource uses filtering, <code>false</code> otherwise.
     */
    private boolean isFilteringEnabled( Resource[] resources )
    {
        for ( Resource resource : resources )
        {
            if ( resource.isFiltering() )
            {
                return true;
            }
        }
        return false;
    }

    static void writeExternal( PrintWriter w, Artifact artifact )
        throws IOException
    {
        w.write( "CRC:" );
        File file = artifact.getFile();
        w.write( Long.toString( CreateClusterAppMojo.crcForFile( file ).getValue() ) );
        w.write( "\nSIZE:" );
        w.write( Long.toString( file.length() ) );
        w.write( "\nURL:m2:/" );
        w.write( artifact.getGroupId() );
        w.write( ':' );
        w.write( artifact.getArtifactId() );
        w.write( ':' );
        w.write( artifact.getVersion() );
        w.write( ':' );
        w.write( artifact.getType() );
        if ( artifact.getClassifier() != null )
        {
            w.write( ':' );
            w.write( artifact.getClassifier() );
        }
        w.write( "\nURL:" );
        // artifact.repository is null, so cannot use its url, and anyway might be a mirror
        w.write( /* M3: RepositorySystem.DEFAULT_REMOTE_REPO_URL + '/' */ "http://repo.maven.apache.org/maven2/" );
        w.write( new DefaultRepositoryLayout().pathOf( artifact ) );
        w.write( '\n' );
        w.flush();
    }

}
