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.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
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.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.GenerateKey;
import org.apache.tools.ant.taskdefs.SignJar;
import org.apache.tools.ant.taskdefs.Taskdef;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Parameter;
import org.apache.tools.ant.types.selectors.AndSelector;
import org.apache.tools.ant.types.selectors.FilenameSelector;
import org.apache.tools.ant.types.selectors.OrSelector;
import org.codehaus.plexus.archiver.zip.ZipArchiver;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.InterpolationFilterReader;
import org.netbeans.nbbuild.MakeJNLP;
import org.netbeans.nbbuild.ModuleSelector;
import org.netbeans.nbbuild.VerifyJNLP;

/**
 * Create webstartable binaries for a 'nbm-application'.
 * @author Johan Andrén
 * @author Milos Kleint
 * @since 3.0
 */
@Mojo( name = "webstart-app", defaultPhase = LifecyclePhase.PACKAGE )
public class CreateWebstartAppMojo
    extends AbstractNbmMojo
{

    /**
     * The Maven project.

     */
    @org.apache.maven.plugins.annotations.Parameter( required = true, readonly = true, property = "project" )
    private MavenProject project;

    @Component
    protected MavenProjectHelper projectHelper;

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

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

    /**
     * Ready-to-deploy WAR containing application in JNLP packaging.
     * 
     */
    @org.apache.maven.plugins.annotations.Parameter( required = true, defaultValue = "${project.build.directory}/${project.artifactId}-${project.version}-jnlp.war" )
    private File destinationFile;

    /**
     * Artifact Classifier to use for the webstart distributable zip file.
     * @since 3.1
     */
    @org.apache.maven.plugins.annotations.Parameter( defaultValue = "webstart", property = "nbm.webstart.classifier" )
    private String webstartClassifier;

    /**
     * Codebase value within *.jnlp files.
     * <strong>Defining this parameter is generally a bad idea.</strong>
     */
    @org.apache.maven.plugins.annotations.Parameter( property = "nbm.webstart.codebase" )
    private String codebase;

    /**
     * A custom master JNLP file. If not defined, the 
     * <a href="http://mojo.codehaus.org/nbm-maven-plugin/masterjnlp.txt">default one</a> is used.
     * The following expressions can be used within the file and will
     * be replaced when generating content.
     * <ul>
     * <li>${jnlp.resources}</li>
     * <li>${jnlp.codebase} - the 'codebase' parameter value is passed in.</li>
     * <li>${app.name}</li>
     * <li>${app.title}</li>
     * <li>${app.vendor}</li>
     * <li>${app.description}</li>
     * <li>${branding.token} - the 'brandingToken' parameter value is passed in.</li>
     * <li>${netbeans.jnlp.fixPolicy}</li>
     * </ul>
     */
    @org.apache.maven.plugins.annotations.Parameter
    private File masterJnlpFile;
    
    /**
     * The basename (minus .jnlp extension) of the master JNLP file in the output.
     * This file will be the entry point for javaws.
     * Defaults to the branding token.
     * @since 3.5
     */
    @org.apache.maven.plugins.annotations.Parameter( property = "master.jnlp.file.name" )
    private String masterJnlpFileName;

    /**
     * keystore location for signing the nbm file
     */
    @org.apache.maven.plugins.annotations.Parameter( property = "keystore" )
    private String keystore;

    /**
     * keystore password
     */
    @org.apache.maven.plugins.annotations.Parameter( property = "keystorepass" )
    private String keystorepassword;

    /**
     * keystore alias
     */
    @org.apache.maven.plugins.annotations.Parameter( property = "keystorealias" )
    private String keystorealias;

    /**
     * keystore type
     * @since 3.5
     */
    @org.apache.maven.plugins.annotations.Parameter( property = "keystoretype" )
    private String keystoretype;

    /**
     * If set true, build-jnlp target creates versioning info in jnlp descriptors and version.xml files.
     * This allows for incremental updates of Webstart applications, but requires download via
     * JnlpDownloadServlet
     * Defaults to false, which means versioning
     * info is not generated (see
     * http://java.sun.com/j2se/1.5.0/docs/guide/javaws/developersguide/downloadservletguide.html#resources).
     *
     */
    @org.apache.maven.plugins.annotations.Parameter( defaultValue = "false", property = "nbm.webstart.versions" )
    private boolean processJarVersions;
    /**
     * additional command line arguments. Eg.
     * -J-Xdebug -J-Xnoagent -J-Xrunjdwp:transport=dt_socket,suspend=n,server=n,address=8888
     * can be used to debug the IDE.
     */
    @org.apache.maven.plugins.annotations.Parameter( property = "netbeans.run.params" )
    private String additionalArguments;

    /**
     * 
     * @throws MojoExecutionException if an unexpected problem occurs
     * @throws MojoFailureException if an expected problem occurs
     */
    @Override
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        if ( !"nbm-application".equals( project.getPackaging() ) )
        {
            throw new MojoExecutionException(
                "This goal only makes sense on project with nbm-application packaging." );
        }
        Project antProject = antProject();
        
        getLog().warn( "WARNING: Unsigned and self-signed WebStart applications are deprecated from JDK7u21 onwards. To ensure future correct functionality please use trusted certificate." );

        if ( keystore != null && keystorealias != null && keystorepassword != null )
        {
            File ks = new File( keystore );
            if ( !ks.exists() )
            {
                throw new MojoFailureException( "Cannot find keystore file at " + ks.getAbsolutePath() );
            }
            else
            {
                //proceed..
            }
        }
        else if ( keystore != null || keystorepassword != null || keystorealias != null )
        {
            throw new MojoFailureException(
                "If you want to sign the jnlp application, you need to define all three keystore related parameters." );
        }
        else
        {
            File generatedKeystore = new File( outputDirectory, "generated.keystore" );
            if ( ! generatedKeystore.exists() )
            {
                getLog().warn( "Keystore related parameters not set, generating a default keystore." );
                GenerateKey genTask = (GenerateKey) antProject.createTask( "genkey" );
                genTask.setAlias( "jnlp" );
                genTask.setStorepass( "netbeans" );
                genTask.setDname( "CN=" + System.getProperty( "user.name" ) );
                genTask.setKeystore( generatedKeystore.getAbsolutePath() );
                genTask.execute();
            }
            keystore = generatedKeystore.getAbsolutePath();
            keystorepassword = "netbeans";
            keystorealias = "jnlp";
        }

        Taskdef taskdef = (Taskdef) antProject.createTask( "taskdef" );
        taskdef.setClassname( "org.netbeans.nbbuild.MakeJNLP" );
        taskdef.setName( "makejnlp" );
        taskdef.execute();

        taskdef = (Taskdef) antProject.createTask( "taskdef" );
        taskdef.setClassname( "org.netbeans.nbbuild.VerifyJNLP" );
        taskdef.setName( "verifyjnlp" );
        taskdef.execute();


        try
        {
            File webstartBuildDir = new File(
                outputDirectory + File.separator + "webstart" + File.separator + brandingToken );
            if ( webstartBuildDir.exists() )
            {
                FileUtils.deleteDirectory( webstartBuildDir );
            }
            webstartBuildDir.mkdirs();
            final String localCodebase = codebase != null ? codebase : webstartBuildDir.toURI().toString();
            getLog().info( "Generating webstartable binaries at " + webstartBuildDir.getAbsolutePath() );

            File nbmBuildDirFile = new File( outputDirectory, brandingToken );

//            FileUtils.copyDirectoryStructureIfModified( nbmBuildDirFile, webstartBuildDir );

            MakeJNLP jnlpTask = (MakeJNLP) antProject.createTask( "makejnlp" );
            jnlpTask.setDir( webstartBuildDir );
            jnlpTask.setCodebase( localCodebase );
            //TODO, how to figure verify excludes..
            jnlpTask.setVerify( false );
            jnlpTask.setPermissions( "<security><all-permissions/></security>" );
            jnlpTask.setSignJars( true );

            jnlpTask.setAlias( keystorealias );
            jnlpTask.setKeystore( keystore );
            jnlpTask.setStorePass( keystorepassword );
            if ( keystoretype != null )
            {
                jnlpTask.setStoreType( keystoretype );
            }
            jnlpTask.setProcessJarVersions( processJarVersions );

            FileSet fs = jnlpTask.createModules();
            fs.setDir( nbmBuildDirFile );
            OrSelector or = new OrSelector();
            AndSelector and = new AndSelector();
            FilenameSelector inc = new FilenameSelector();
            inc.setName( "*/modules/**/*.jar" );
            or.addFilename( inc );
            inc = new FilenameSelector();
            inc.setName( "*/lib/**/*.jar" );
            or.addFilename( inc );
            inc = new FilenameSelector();
            inc.setName( "*/core/**/*.jar" );
            or.addFilename( inc );

            ModuleSelector ms = new ModuleSelector();
            Parameter included = new Parameter();
            included.setName( "includeClusters" );
            included.setValue( "" );
            Parameter excluded = new Parameter();
            excluded.setName( "excludeClusters" );
            excluded.setValue( "" );
            Parameter exModules = new Parameter();
            exModules.setName( "excludeModules" );
            exModules.setValue( "" );
            ms.setParameters( new Parameter[]
                {
                    included,
                    excluded,
                    exModules
                } );
            and.add( or );
            and.add( ms );
            fs.addAnd( and );
            jnlpTask.execute();

            //TODO is it really netbeans/
            String extSnippet = generateExtensions( fs, antProject, "" ); // "netbeans/"

            if ( masterJnlpFileName == null )
            {
               masterJnlpFileName = brandingToken;
            }

            Properties props = new Properties();
            props.setProperty( "jnlp.codebase", localCodebase );
            props.setProperty( "app.name", brandingToken );
            props.setProperty( "app.title", project.getName() );
            if ( project.getOrganization() != null )
            {
                props.setProperty( "app.vendor", project.getOrganization().getName() );
            }
            else
            {
                props.setProperty( "app.vendor", "Nobody" );
            }
            String description = project.getDescription() != null ? project.getDescription() : "No Project Description";
            props.setProperty( "app.description", description );
            props.setProperty( "branding.token", brandingToken );
            props.setProperty( "master.jnlp.file.name", masterJnlpFileName );
            props.setProperty( "netbeans.jnlp.fixPolicy", "false" );

            StringBuilder stBuilder = new StringBuilder();
            if ( additionalArguments != null )
            {
                StringTokenizer st = new StringTokenizer( additionalArguments );
                while ( st.hasMoreTokens() )
                {
                    String arg = st.nextToken();
                    if ( arg.startsWith( "-J" ) )
                    {
                        if ( stBuilder.length() > 0 )
                        {
                            stBuilder.append( ' ' );
                        }
                        stBuilder.append( arg.substring( 2 ) );
                    }
                }
            }
            props.setProperty( "netbeans.run.params", stBuilder.toString() );

            File masterJnlp = new File(
                webstartBuildDir.getAbsolutePath() + File.separator + masterJnlpFileName + ".jnlp" );
            filterCopy( masterJnlpFile, "master.jnlp", masterJnlp, props );


            File startup = copyLauncher( outputDirectory, nbmBuildDirFile );
            File jnlpDestination = new File(
                webstartBuildDir.getAbsolutePath() + File.separator + "startup.jar" );

            SignJar signTask = (SignJar) antProject.createTask( "signjar" );
            signTask.setKeystore( keystore );
            signTask.setStorepass( keystorepassword );
            signTask.setAlias( keystorealias );
            if ( keystoretype != null )
            {
                signTask.setStoretype( keystoretype );
            }
            signTask.setSignedjar( jnlpDestination );
            signTask.setJar( startup );
            signTask.execute();

            //branding
            DirectoryScanner ds = new DirectoryScanner();
            ds.setBasedir( nbmBuildDirFile );
            ds.setIncludes( new String[]
                {
                    "**/locale/*.jar"
                } );
            ds.scan();
            String[] includes = ds.getIncludedFiles();
            StringBuilder brandRefs = new StringBuilder();
            if ( includes != null && includes.length > 0 )
            {
                File brandingDir = new File( webstartBuildDir, "branding" );
                brandingDir.mkdirs();
                for ( String incBran : includes )
                {
                    File source = new File( nbmBuildDirFile, incBran );
                    File dest = new File( brandingDir, source.getName() );
                    FileUtils.copyFile( source, dest );
                    brandRefs.append( "    <jar href=\'branding/" ).append( dest.getName() ).append( "\'/>\n" );
                }

                signTask = (SignJar) antProject.createTask( "signjar" );
                signTask.setKeystore( keystore );
                signTask.setStorepass( keystorepassword );
                signTask.setAlias( keystorealias );
                if ( keystoretype != null )
                {
                    signTask.setStoretype( keystoretype );
                }
                
                FileSet set = new FileSet();
                set.setDir( brandingDir );
                set.setIncludes( "*.jar" );
                signTask.addFileset( set );
                signTask.execute();
            }

            File modulesJnlp = new File(
                webstartBuildDir.getAbsolutePath() + File.separator + "modules.jnlp" );
            props.setProperty( "jnlp.branding.jars", brandRefs.toString() );
            props.setProperty( "jnlp.resources", extSnippet );
            filterCopy( null, /* filename is historical */"branding.jnlp", modulesJnlp, props );

            getLog().info( "Verifying generated webstartable content." );
            VerifyJNLP verifyTask = (VerifyJNLP) antProject.createTask( "verifyjnlp" );
            FileSet verify = new FileSet();
            verify.setFile( masterJnlp );
            verifyTask.addConfiguredFileset( verify );
            verifyTask.execute();


            // create zip archive
            if ( destinationFile.exists() )
            {
                destinationFile.delete();
            }
            ZipArchiver archiver = new ZipArchiver();
            if ( codebase != null )
            {
                getLog().warn( "Defining <codebase>/${nbm.webstart.codebase} is generally unnecessary" );
                archiver.addDirectory( webstartBuildDir );
            }
            else
            {
                archiver.addDirectory( webstartBuildDir, null, new String[] { "**/*.jnlp" } );
                for ( final File jnlp : webstartBuildDir.listFiles() )
                {
                    if ( !jnlp.getName().endsWith( ".jnlp" ) )
                    {
                        continue;
                    }
                    archiver.addResource( new PlexusIoResource()
                    {
                        public @Override InputStream getContents() throws IOException
                        {
                            return new ByteArrayInputStream( FileUtils.fileRead( jnlp, "UTF-8" ).replace( localCodebase, "$$codebase" ).getBytes( "UTF-8" ) );
                        }
                        public @Override long getLastModified()
                        {
                            return jnlp.lastModified();
                        }
                        public @Override boolean isExisting()
                        {
                            return true;
                        }
                        public @Override long getSize()
                        {
                            return UNKNOWN_RESOURCE_SIZE;
                        }
                        public @Override URL getURL() throws IOException
                        {
                            return null;
                        }
                        public @Override String getName()
                        {
                            return jnlp.getAbsolutePath();
                        }
                        public @Override boolean isFile()
                        {
                            return true;
                        }
                        public @Override boolean isDirectory()
                        {
                            return false;
                        }

                        @Override
                        public boolean isSymbolicLink()
                        {
                            return false;
                        }
                    }, jnlp.getName(), archiver.getDefaultFileMode() );
                }
            }
            File jdkhome = new File( System.getProperty( "java.home" ) );
            File servlet = new File( jdkhome, "sample/jnlp/servlet/jnlp-servlet.jar" );
            if ( ! servlet.isFile() )
            {
                servlet = new File( jdkhome.getParentFile(), "sample/jnlp/servlet/jnlp-servlet.jar" );
            }
            if ( servlet.isFile() )
            {
                archiver.addFile( servlet, "WEB-INF/lib/jnlp-servlet.jar" );
                archiver.addResource( new PlexusIoResource()
                {
                    public @Override InputStream getContents() throws IOException
                    {
                        return new ByteArrayInputStream( ( "" 
                            + "<web-app>\n"
                            + "    <servlet>\n"
                            + "        <servlet-name>JnlpDownloadServlet</servlet-name>\n"
                            + "        <servlet-class>jnlp.sample.servlet.JnlpDownloadServlet</servlet-class>\n"
                            + "    </servlet>\n"
                            + "    <servlet-mapping>\n"
                            + "        <servlet-name>JnlpDownloadServlet</servlet-name>\n"
                            + "        <url-pattern>*.jnlp</url-pattern>\n"
                            + "    </servlet-mapping>\n"
                            + "</web-app>\n" ).getBytes() );
                    }
                    public @Override long getLastModified()
                    {
                        return UNKNOWN_MODIFICATION_DATE;
                    }
                    public @Override boolean isExisting()
                    {
                        return true;
                    }
                    public @Override long getSize()
                    {
                        return UNKNOWN_RESOURCE_SIZE;
                    }
                    public @Override URL getURL() throws IOException
                    {
                        return null;
                    }
                    public @Override String getName()
                    {
                        return "web.xml";
                    }
                    public @Override boolean isFile()
                    {
                        return true;
                    }
                    public @Override boolean isDirectory()
                    {
                        return false;
                    }

                    @Override
                    public boolean isSymbolicLink()
                    {
                        return false;
                    }
                }, "WEB-INF/web.xml", archiver.getDefaultFileMode() );
            }
            archiver.setDestFile( destinationFile );
            archiver.createArchive();

            // attach standalone so that it gets installed/deployed
            projectHelper.attachArtifact( project, "war", webstartClassifier, destinationFile );

        }
        catch ( Exception ex )
        {
            throw new MojoExecutionException( "Error creating webstartable binary.", ex );
        }
    }

    /**
     * @param standaloneBuildDir
     * @return The name of the jnlp-launcher jarfile in the build directory
     */
    private File copyLauncher( File standaloneBuildDir, File builtInstallation )
        throws IOException
    {
        File jnlpStarter =
            new File( builtInstallation.getAbsolutePath() + File.separator + "harness" + File.separator + "jnlp"
                + File.separator + "jnlp-launcher.jar" );
        // buffer so it isn't reading a byte at a time!
        InputStream source = null;
        FileOutputStream outstream = null;
        try
        {
            if ( !jnlpStarter.exists() )
            {
                source = getClass().getClassLoader().getResourceAsStream(
                    "harness/jnlp/jnlp-launcher.jar" );
            }
            else
            {
                source = new FileInputStream( jnlpStarter );
            }
            File jnlpDestination = new File(
                standaloneBuildDir.getAbsolutePath() + File.separator + "jnlp-launcher.jar" );

            outstream = new FileOutputStream( jnlpDestination );
            IOUtil.copy( source, outstream );
            return jnlpDestination;
        }
        finally
        {
            IOUtil.close( source );
            IOUtil.close( outstream );
        }
    }

    private void filterCopy( File sourceFile, String resourcePath, File destinationFile, Properties filterProperties )
        throws IOException
    {
        // buffer so it isn't reading a byte at a time!
        Reader source = null;
        Writer destination = null;
        try
        {
            InputStream instream;
            if ( sourceFile != null )
            {
                instream = new FileInputStream( sourceFile );
            }
            else
            {
                instream = getClass().getClassLoader().getResourceAsStream( resourcePath );
            }
            FileOutputStream outstream = new FileOutputStream( destinationFile );

            source = new BufferedReader( new InputStreamReader( instream, "UTF-8" ) );
            destination = new OutputStreamWriter( outstream, "UTF-8" );

            // support ${token}
            Reader reader = new InterpolationFilterReader( source, filterProperties, "${", "}" );

            IOUtil.copy( reader, destination );
        }
        finally
        {
            IOUtil.close( source );
            IOUtil.close( destination );
        }
    }

    /**
     * copied from MakeMasterJNLP ant task.
     * @param files
     * @param antProject
     * @param masterPrefix
     * @return
     * @throws java.io.IOException
     */
    private String generateExtensions( FileSet files, Project antProject, String masterPrefix )
        throws IOException
    {
        StringBuilder buff = new StringBuilder();
        for ( String nm : files.getDirectoryScanner( antProject ).getIncludedFiles() )
        {
            File jar = new File( files.getDir( antProject ), nm );

            if ( !jar.canRead() )
            {
                throw new IOException( "Cannot read file: " + jar );
            }

            JarFile theJar = new JarFile( jar );
            Attributes attr = theJar.getManifest().getMainAttributes();
            String codenamebase = attr.getValue( "OpenIDE-Module" );
            if ( codenamebase == null )
            {
                codenamebase = attr.getValue( "Bundle-SymbolicName" );
            }
            if ( codenamebase == null )
            {
                throw new IOException( "Not a NetBeans Module: " + jar );
            }
            
            // see http://hg.netbeans.org/main-silver/rev/87823abb86d9
            if ( codenamebase.equals( "org.objectweb.asm.all" )
                    && jar.getParentFile().getName().equals( "core" )
                    && jar.getParentFile().getParentFile().getName().startsWith( "platform" ) )
            {
                continue;
            }
            {
                int slash = codenamebase.indexOf( '/' );
                if ( slash >= 0 )
                {
                    codenamebase = codenamebase.substring( 0, slash );
                }
            }
            String dashcnb = codenamebase.replace( '.', '-' );

            buff.append( "    <extension name='" ).append( codenamebase ).append( "' href='" ).append( masterPrefix ).append( dashcnb ).append( ".jnlp' />\n" );
            theJar.close();
        }
        return buff.toString();

    }
}
