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

import java.io.*;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.jar.JarEntry;
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.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.util.StringUtils;

/**
 * Build installers for Mavenized NetBeans application.
 * Creates installers for supported operating systems
 * and packages each installer as a deployable artifact.
 * <p>See a <a href="http://www.mojohaus.org/nbm-maven-plugin/buildinstexample.html">how-to</a> on customizing the installer.
 * @author <a href="mailto:frantisek@mantlik.cz">Frantisek Mantlik</a>
 */
@Mojo(name="build-installers", 
        requiresProject=true, 
        requiresDependencyResolution=ResolutionScope.RUNTIME,
        threadSafe = true,
        defaultPhase=LifecyclePhase.PACKAGE )
public class BuildInstallersMojo
        extends AbstractNbmMojo
{

    /**
    * output directory.
    */
    @Parameter(defaultValue="${project.build.directory}", required=true)
    protected File outputDirectory;
    /**
    * The branding token for the application based on NetBeans platform.
    */
    @Parameter(property="netbeans.branding.token", required=true)
    protected String brandingToken;
    /**
    * Installation directory name at the destination system
    * Deprecated, to be removed, was never actually used.
    */
    @Parameter(property="netbeans.branding.token")
    protected String installDirName;
    /**
    * Prefix of all generated installers files
    */
    @Parameter(defaultValue="${project.build.finalName}")
    private String installersFilePrefix;
    /**
     * Create installer for Windows
     */
    @Parameter(defaultValue="true")
    private boolean installerOsWindows;
    /**
     * Create installer for Solaris
     */
    @Parameter(defaultValue="true")
    private boolean installerOsSolaris;
    /**
     * Create installer for Linux
     */
    @Parameter(defaultValue="true")    
    private boolean installerOsLinux;
    /**
     * Create installer for MacOSx
     */
    @Parameter(defaultValue="true")    
    private boolean installerOsMacosx;
    /**
     * Enable Pack200 compression
     */
    @Parameter(defaultValue="true")
    private boolean installerPack200Enable;
    /**
     * License file
     */
    @Parameter(defaultValue="${basedir}/license.txt")
    private File installerLicenseFile;
    /**
     * Custom installer template.
     * This file, if provided, will replace default template from
     * &lt;NetBeansInstallation&gt;/harness/nbi/stub/template.xml
     */
    @Parameter
    private File templateFile;
    /**
     * Parameters passed to templateFile 
     * or to installer/nbi/stub/template.xml 
     * to customize generated installers.
     *
     */
    @Parameter
    private Map<String, String> userSettings;
    
    /**
     * Name of the zip artifact used to produce installers from (without .zip extension)
     */
    @Parameter(defaultValue="${project.build.finalName}")
    private String finalName;

    // <editor-fold defaultstate="collapsed" desc="Component parameters">
    /**
     * Used for attaching the artifact in the project
     */
    @Component
    private MavenProjectHelper projectHelper;
        
    @Parameter(readonly=true, required=true, property="basedir")
    private File basedir;
    /**
    * The Maven Project.
    */
    @Parameter(required=true, readonly=true, property="project")    
    private MavenProject project;    

    // </editor-fold>
    @Override
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        Project antProject = antProject();

        if ( !"nbm-application".equals( project.getPackaging() ) )
        {
            throw new MojoExecutionException(
                    "This goal only makes sense on project with 'nbm-application' packaging." );
        }
        
        if (!installerOsLinux && !installerOsMacosx && !installerOsSolaris && !installerOsWindows) {
            getLog().warn( "None of the Operating System Installers selected, skipping 'build-installers' goal.");
            return;
        }

        String zipName = finalName + ".zip";
        File zipFile = new File( outputDirectory, zipName );
        getLog().info( String.format( "Running Build Installers action for (existing=%2$s) zip file %1$s",
                zipFile, zipFile.exists() ) );


        File appIconIcnsFile;

        // Copy Netbeans Installer resources
        FileUrlUtils fu = new FileUrlUtils();
        File harnessDir = new File( outputDirectory, "installer" );
        fu.copyResourcesRecursively( getClass().getClassLoader().getResource( "harness" ), harnessDir );

        // Overwrite template file with modified version to accept branded images etc.
        if ( templateFile != null )
        {
            File template = new File( harnessDir, "nbi/stub/template.xml" );
            fu.copyFile( templateFile, template );
        }

        appIconIcnsFile = new File( harnessDir, "etc" + File.separatorChar + "applicationIcon.icns" );
        getLog().info( "Application icon:" + appIconIcnsFile.getAbsolutePath() );

        Map<String, String> props = new HashMap<String, String> ();

        props.put( "suite.location", basedir.getAbsolutePath().replace( "\\", "/" ) );
        props.put( "suite.props.app.name", brandingToken);
        props.put( "suite.dist.zip", zipFile.getAbsolutePath().replace( "\\", "/" ) );
        props.put( "suite.dist.directory", outputDirectory.getAbsolutePath().replace( "\\", "/" ) );
        props.put( "installer.build.dir", new File( outputDirectory, "installerbuild" ).getAbsolutePath().replace( "\\", "/" ) );
        
        props.put( "installers.file.prefix", installersFilePrefix );

//        props.put( "install.dir.name", installDirName );

        //mkleint: this is a flawed pattern! cannot make any assumption on multimodule layout
        String appName = project.getParent().getArtifactId().replace( ".", "" ).replace( "-", "" ).replace( "_", "" ).replaceAll( "[0-9]+", "" );
        props.put( "suite.nbi.product.uid", appName.toLowerCase( Locale.ENGLISH ) );

        props.put( "suite.props.app.title", ( project.getName() + " " + project.getVersion() ).replaceAll( "-SNAPSHOT", "" ) );

        String appVersion = project.getVersion().replaceAll( "-SNAPSHOT", "" );
        props.put( "suite.nbi.product.version.short", appVersion );
        while ( appVersion.split( "\\." ).length < 5 )
        {
            appVersion += ".0";
        }
        props.put( "suite.nbi.product.version", appVersion );

        props.put( "nbi.stub.location", new File( harnessDir, "nbi/stub" ).getAbsolutePath().replace( "\\", "/" ) );

        props.put( "nbi.stub.common.location", new File( harnessDir, "nbi/.common" ).getAbsolutePath().replace( "\\", "/" ) );

        props.put( "nbi.ant.tasks.jar", new File( harnessDir, "modules/ext/nbi-ant-tasks.jar" ).getAbsolutePath().replace( "\\", "/" ) );

        props.put( "nbi.registries.management.jar", new File( harnessDir, "modules/ext/nbi-registries-management.jar" ).getAbsolutePath().replace( "\\", "/" ) );

        props.put( "nbi.engine.jar", new File( harnessDir, "modules/ext/nbi-engine.jar" ).getAbsolutePath().replace( "\\", "/" ) );

        if ( installerLicenseFile != null )
        {
            getLog().info( String.format( "License file is at %1s, exist = %2$s", installerLicenseFile, installerLicenseFile.exists() ) );
            props.put( "nbi.license.file", installerLicenseFile.getAbsolutePath() ); //mkleint: no path replacement here??
        }

        List<String> platforms = new ArrayList<String>();

        if ( this.installerOsLinux )
        {
            platforms.add( "linux" );
            File linuxFile = new File( outputDirectory, installersFilePrefix + "-linux.sh" );
            projectHelper.attachArtifact( project, "sh", "linux", linuxFile );
        }
        if ( this.installerOsSolaris )
        {
            platforms.add( "solaris" );
            File solarisFile = new File( outputDirectory, installersFilePrefix + "-solaris.sh" );
            projectHelper.attachArtifact( project, "sh", "solaris", solarisFile );
        }
        if ( this.installerOsWindows )
        {
            platforms.add( "windows" );
            File windowsFile = new File( outputDirectory, installersFilePrefix + "-windows.exe" );
            projectHelper.attachArtifact( project, "exe", "windows", windowsFile );
        }
        if ( this.installerOsMacosx )
        {
            platforms.add( "macosx" );
            File macosxFile = new File( outputDirectory, installersFilePrefix + "-macosx.tgz" );
            projectHelper.attachArtifact( project, "tgz", "macosx", macosxFile );
        }

        StringBuilder sb = new StringBuilder();
        for ( int i = 0; i < platforms.size(); i++ )
        {
            if ( i != 0 )
            {
                sb.append( " " );
            }
            sb.append( platforms.get( i ) );
        }
        if ( sb.length() == 0 )
        {
            //nothing to build
            getLog().warn( "Nothing to build." );
        }

        props.put( "generate.installer.for.platforms", sb.toString() );

        File javaHome = new File( System.getProperty( "java.home" ) );
        if ( new File( javaHome, "lib/rt.jar" ).exists() && javaHome.getName().equals( "jre" ) ) //mkleint: does this work on mac? no rt.jar there
        {
            javaHome = javaHome.getParentFile();
        }
        props.put( "generator-jdk-location-forward-slashes", javaHome.getAbsolutePath().replace( "\\", "/" ) );

        props.put( "pack200.enabled", "" + installerPack200Enable );

        if ( appIconIcnsFile != null )
        {
            props.put( "nbi.dock.icon.file", appIconIcnsFile.getAbsolutePath() );
        }

        try
        {
            antProject.setUserProperty( "ant.file", new File( harnessDir, "nbi/stub/template.xml" ).getAbsolutePath().replace( "\\", "/" ) );
            ProjectHelper helper = ProjectHelper.getProjectHelper();
            antProject.addReference( "ant.projectHelper", helper );
            helper.parse( antProject, new File( harnessDir, "nbi/stub/template.xml" ) );
            for ( Map.Entry<String, String> e : props.entrySet() )
            {
                antProject.setProperty( e.getKey(), e.getValue() );
            }
            if ( userSettings != null )
            {
                for ( Map.Entry<String, String> e : userSettings.entrySet() )
                {
                    antProject.setProperty( e.getKey(), e.getValue() );
                }
            }
            antProject.executeTarget( "build" );
        }
        catch ( Exception ex )
        {
            throw new MojoExecutionException( "Installers creation failed: " + ex, ex );
        }
    }

    //mkleint: could this be replaced by something from plexus-utils?
    private class FileUrlUtils
    {

        boolean copyFile( final File toCopy, final File destFile )
            throws MojoExecutionException
        {
            try
            {
                return copyStream( new FileInputStream( toCopy ), new FileOutputStream( destFile ) );
            }
            catch ( final FileNotFoundException e )
            {
                throw new MojoExecutionException( "Installers creation failed: " + e, e );
            }
        }

        boolean copyFilesRecusively( final File toCopy, final File destDir )
            throws MojoExecutionException
        {
            assert destDir.isDirectory();

            if ( !toCopy.isDirectory() )
            {
                return copyFile( toCopy, new File( destDir, toCopy.getName() ) );
            }
            else
            {
                final File newDestDir = new File( destDir, toCopy.getName() );
                if ( !newDestDir.exists() && !newDestDir.mkdir() )
                {
                    return false;
                }
                for ( final File child : toCopy.listFiles() )
                {
                    if ( !copyFilesRecusively( child, newDestDir ) )
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        boolean copyJarResourcesRecursively( final File destDir, final JarURLConnection jarConnection )
            throws IOException, MojoExecutionException
        {

            final JarFile jarFile = jarConnection.getJarFile();

            for ( final Enumeration<JarEntry> e = jarFile.entries(); e.hasMoreElements(); )
            {
                final JarEntry entry = e.nextElement();
                if ( entry.getName().startsWith( jarConnection.getEntryName() ) )
                {
                    final String filename = StringUtils.removePrefix( entry.getName(), //
                            jarConnection.getEntryName() );

                    final File f = new File( destDir, filename );
                    if ( !entry.isDirectory() )
                    {
                        final InputStream entryInputStream = jarFile.getInputStream( entry );
                        if ( !copyStream( entryInputStream, f ) )
                        {
                            return false;
                        }
                        entryInputStream.close();
                    }
                    else
                    {
                        if ( !ensureDirectoryExists( f ) )
                        {
                            throw new IOException( "Could not create directory: "
                                    + f.getAbsolutePath() );
                        }
                    }
                }
            }
            return true;
        }

        boolean copyResourcesRecursively( final URL originUrl, final File destination )
            throws MojoExecutionException
        {
            try
            {
                final URLConnection urlConnection = originUrl.openConnection();
                if ( urlConnection instanceof JarURLConnection )
                {
                    return copyJarResourcesRecursively( destination, (JarURLConnection) urlConnection );
                }
                else
                {
                    return copyFilesRecusively( new File( originUrl.getPath() ), destination );
                }
            }
            catch ( final IOException e )
            {
                throw new MojoExecutionException( "Installers creation failed: " + e, e );
            }
        }

        boolean copyStream( final InputStream is, final File f )
            throws MojoExecutionException
        {
            try
            {
                return copyStream( is, new FileOutputStream( f ) );
            }
            catch ( final FileNotFoundException e )
            {
                throw new MojoExecutionException( "Installers creation failed: " + e, e );
            }
        }

        boolean copyStream( final InputStream is, final OutputStream os )
            throws MojoExecutionException
        {
            try
            {
                final byte[] buf = new byte[1024];

                int len;
                while ( ( len = is.read( buf ) ) > 0 )
                {
                    os.write( buf, 0, len );
                }
                is.close();
                os.close();
                return true;
            }
            catch ( final IOException e )
            {
                throw new MojoExecutionException( "Installers creation failed: " + e, e );
            }
        }

        boolean ensureDirectoryExists( final File f )
        {
            return f.exists() || f.mkdir();
        }
    }
}
