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.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
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();
        }
    }
}
