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.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.Developer;
import org.apache.maven.model.License;
import org.apache.maven.model.Organization;
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.MavenProjectHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.util.FileUtils;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import org.netbeans.nbbuild.MakeNBM;
import org.netbeans.nbbuild.MakeNBM.Blurb;
import org.netbeans.nbbuild.MakeNBM.Signature;

/**
 * Create the NetBeans module artifact (nbm file), part of "nbm" lifecycle/packaging.
 *
 *
 * @author Milos Kleint
 */
@Mojo( name = "nbm",
        requiresProject = true,
        threadSafe = true,
        requiresDependencyResolution = ResolutionScope.RUNTIME,
        defaultPhase = LifecyclePhase.PACKAGE )
public class CreateNbmMojo
        extends CreateNetBeansFileStructure
        implements Contextualizable
{

    /**
     * keystore location for signing the nbm file
     */
    @Parameter( property = "keystore" )
    private String keystore;
    /**
     * keystore password
     */
    @Parameter( property = "keystorepass" )
    private String keystorepassword;
    /**
     * keystore alias
     */
    @Parameter( property = "keystorealias" )
    private String keystorealias;
    /**
     * Timestamp Authority (TSA) URL
     */
    @Parameter( property = "tsaurl" )
    private String tsaurl;
    /**
     * Timestamp Authority (TSA) Certificate
     */
    @Parameter( property = "tsacert" )
    private String tsacert;

    /**
     * Boolean parameter denoting if creation of NBM file shall be skipped or not. If skipped, just the expanded
     * directory for cluster is created
     *
     * @since 3.0
     */
    @Parameter( defaultValue = "false", property = "maven.nbm.skip" )
    private boolean skipNbm;

    /**
     * if true, upon installing the NBM the platform app/IDE restart is requested. Not necessary in most cases.
     *
     * @since 3.8
     */
    @Parameter( defaultValue = "false" )
    private boolean requiresRestart;

    /**
     * Get homepage URL of the module. Is accessible from NetBeans UI upon installation, should point to place with
     * additional information about the functionality.
     *
     * @since 3.8
     */
    @Parameter( defaultValue = "${project.url}" )
    private String homePageUrl;

    /**
     * Author of the module. Shown in the Module manager UI.
     *
     * @since 3.8
     */
    @Parameter( defaultValue = "${project.organization.name}" )
    private String author;

    /**
     * Distribution base URL for the NBM at runtime deployment time. Note: Usefulness of the parameter is questionable,
     * it doesn't allow for mirrors and usually when downloading the nbm, one already knows the location anyway. Please
     * note that the netbeans.org Ant scripts put a dummy url here. The actual correct value used when constructing
     * update site is explicitly set there. The general assumption there is that all modules from one update center come
     * from one base URL. Also see <code>distBase</code> parameter in auto-update mojo.
     * <p/>
     * The value is either a direct http protocol based URL that points to the location under which nbm file will be
     * located, or
     * <p/>
     * it allows to create an update site based on maven repository content. The later created autoupdate site document
     * can use this information and compose the application from one or multiple maven repositories.
     * <br/>
     * Format: id::layout::url same as in maven-deploy-plugin
     * <br/>
     * with the 'default' and 'legacy' layouts. (maven2 vs maven1 layout)
     * <br/>
     * If the value doesn't contain :: characters, it's assumed to be the flat structure and the value is just the URL.
     *
     */
    @Parameter( property = "maven.nbm.distributionURL" )
    private String distributionUrl;

    /**
     * name of the license applicable to the NBM. The value should be equal across modules with the same license. If the
     * user already agreed to the same license before, he/she won't be asked again to agree and for multiple one
     * installed at the same time, just one license agreement is shown. When defined, <code>licenseFile</code> needs to
     * be defined as well.
     *
     * @since 3.8
     */
    @Parameter
    private String licenseName;

    /**
     * path to the license agreement file that will be shown when installing the module. When defined,
     * <code>licenseName</code> needs to be defined as well.
     *
     * @since 3.8
     */
    @Parameter
    private File licenseFile;

    // <editor-fold defaultstate="collapsed" desc="Component parameters">
    /**
     * Contextualized.
     */
    private PlexusContainer container;

    @Component
    private ArtifactFactory artifactFactory;
    /**
     * Used for attaching the artifact in the project
     */
    @Component
    private MavenProjectHelper projectHelper;

    // end of component params custom code folding
    // </editor-fold>
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat( "yyyy/MM/dd" );

    public void execute()
            throws MojoExecutionException, MojoFailureException
    {
        if ( skipNbm )
        {
            getLog().info( "Skipping generation of NBM file." );
            return;
        }

        if ( "pom".equals( project.getPackaging() ) )
        {
            getLog().info(
                    "Skipping " + project.getId() + ", no nbm:nbm execution for 'pom' packaging" );
            return;
        }
        super.execute();

        // 3. generate nbm
        File nbmFile = new File( nbmBuildDir, finalName + ".nbm" );
        MakeNBM nbmTask = (MakeNBM) antProject.createTask( "makenbm" );
        nbmTask.setFile( nbmFile );
        nbmTask.setProductDir( clusterDir );

        nbmTask.setModule( "modules" + File.separator + moduleJarName + ".jar" );
        boolean reqRestart = requiresRestart;
        if ( !reqRestart && module.isRequiresRestart() )
        {
            reqRestart = module.isRequiresRestart();
            getLog().warn(
                    "Module descriptor's requiresRestart field is deprecated, use plugin's configuration in pom.xml" );
        }
        nbmTask.setNeedsrestart( Boolean.toString( reqRestart ) );
        String moduleAuthor = author;
        if ( module.getAuthor() != null )
        {
            moduleAuthor = module.getAuthor();
            getLog().warn(
                    "Module descriptor's requiresRestart field is deprecated, use plugin's configuration in pom.xml" );
        }
        nbmTask.setModuleauthor( moduleAuthor );
        if ( keystore != null && keystorealias != null && keystorepassword != null )
        {
            File ks = new File( keystore );
            if ( !ks.exists() )
            {
                getLog().warn( "Cannot find keystore file at " + ks.getAbsolutePath() );
            }
            else
            {
                Signature sig = nbmTask.createSignature();
                sig.setKeystore( ks );
                sig.setAlias( keystorealias );
                sig.setStorepass( keystorepassword );
                if ( tsaurl != null ) 
                {
                    sig.setTsaurl( tsaurl );
                }
                if ( tsacert != null ) 
                {
                    sig.setTsacert( tsacert );
                }
                getLog().debug( "Setup the Ant task to sign the NBM file." );
            }
        }
        else if ( keystore != null || keystorepassword != null || keystorealias != null )
        {
            getLog().warn(
                    "If you want to sign the nbm file, you need to define all three keystore related parameters." );
        }
        String licName = licenseName;
        File licFile = licenseFile;
        if ( module.getLicenseName() != null )
        {
            licName = module.getLicenseName();
            getLog().warn(
                    "Module descriptor's licenseName field is deprecated, use plugin's configuration in pom.xml" );
        }
        if ( module.getLicenseFile() != null )
        {
            File lf = new File( project.getBasedir(), module.getLicenseFile() );
            licFile = lf;
            getLog().warn(
                    "Module descriptor's licenseFile field is deprecated, use plugin's configuration in pom.xml" );

        }
        if ( licName != null && licFile != null )
        {
            if ( !licFile.exists() || !licFile.isFile() )
            {
                getLog().warn( "Cannot find license file at " + licFile.getAbsolutePath() );
            }
            else
            {
                Blurb lb = nbmTask.createLicense();
                lb.setFile( licFile );
                lb.addText( licName );
            }
        }
        else if ( licName != null || licFile != null )
        {
            getLog().warn(
                    "To set license for the nbm, you need to specify both licenseName and licenseFile parameters." );
        }
        else
        {
            Blurb lb = nbmTask.createLicense();
            lb.addText( createDefaultLicenseHeader() );
            lb.addText( createDefaultLicenseText() );
        }
        String hpUrl = homePageUrl;
        if ( module.getHomepageUrl() != null )
        {
            getLog().warn(
                    "Module descriptor's homePageUrl field is deprecated, use plugin's configuration in pom.xml" );
            hpUrl = module.getHomepageUrl();
        }
        if ( hpUrl != null )
        {
            nbmTask.setHomepage( hpUrl );
        }
        String distribUrl = distributionUrl;
        if ( module.getDistributionUrl() != null )
        {
            distribUrl = module.getDistributionUrl();
            getLog().warn(
                    "Module descriptor's distributionUrl field is deprecated, use plugin's configuration in pom.xml" );
        }
        if ( distribUrl != null )
        {
            ArtifactRepository distRepository = CreateUpdateSiteMojo.getDeploymentRepository(
                    distribUrl, container, getLog() );
            String dist = null;
            if ( distRepository == null )
            {
                if ( !distribUrl.contains( "::" ) )
                {
                    dist
                            = distribUrl + ( distribUrl.endsWith( "/" ) ? "" : "/" )
                            + nbmFile.getName();
                }
            }
            else
            {
                Artifact art = artifactFactory.createArtifact(
                        project.getGroupId(), project.getArtifactId(),
                        project.getVersion(), null, "nbm-file" );

                dist
                        = distRepository.getUrl() + ( distRepository.getUrl().endsWith( "/" ) ? "" : "/" )
                        + distRepository.pathOf( art );

            }
            nbmTask.setDistribution( dist );
        }
        else
        {
            nbmTask.setDistribution( nbmFile.getName() );
        }
        if ( !"extra".equals( cluster ) )
        {
            nbmTask.setTargetcluster( cluster );
        }
        //MNBMODULE-217 avoid using the static DATE_FORMAT variable in MavenNBM.java (in ant harness)
        nbmTask.setReleasedate( DATE_FORMAT.format( new Date( System.currentTimeMillis() ) ) );
        try
        {
            nbmTask.execute();
        }
        catch ( BuildException e )
        {
            throw new MojoExecutionException( "Cannot Generate nbm file:" + e.getMessage(), e );
        }
        try
        {
            File nbmfile = new File( buildDir, nbmFile.getName() );
            FileUtils.getFileUtils().copyFile( nbmFile, nbmfile );
            projectHelper.attachArtifact( project, "nbm-file", null, nbmfile );
        }
        catch ( IOException ex )
        {
            throw new MojoExecutionException( "Cannot copy nbm to build directory", ex );
        }
    }

    @Override
    public void contextualize( Context context )
            throws ContextException
    {
        this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
    }

    private String createDefaultLicenseHeader()
    {
        String organization = "";
        Organization org = project.getOrganization();
        if ( org != null )
        {
            organization = org.getName();
        }
        if ( organization == null )
        {
            List devs = project.getDevelopers();
            if ( devs.size() > 0 )
            {
                Iterator dvs = devs.iterator();
                String devsString = "";
                while ( dvs.hasNext() )
                {
                    Developer d = (Developer) dvs.next();
                    devsString = devsString + "," + d.getName() != null ? d.getName() : d.getId();
                }
                organization = devsString.substring( 1 );
            }
        }
        if ( organization == null )
        {
            organization = ""; //what's a good default value?
        }
        String date = "";
        if ( project.getInceptionYear() != null )
        {
            date = project.getInceptionYear();
        }
        String year = Integer.toString( Calendar.getInstance().get( Calendar.YEAR ) );
        if ( !year.equals( date ) )
        {
            date = date.length() == 0 ? year : date + "-" + year;
        }
        return "Copyright " + organization + " " + date;
    }

    private String createDefaultLicenseText()
    {
        String toRet = "License terms:\n";

        List licenses = project.getLicenses();
        if ( licenses != null && licenses.size() > 0 )
        {
            Iterator lic = licenses.iterator();
            while ( lic.hasNext() )
            {
                License ll = (License) lic.next();

                if ( ll.getName() != null )
                {
                    toRet = toRet + ll.getName() + " - ";
                }
                if ( ll.getUrl() != null )
                {
                    toRet = toRet + ll.getUrl();
                }
                if ( lic.hasNext() )
                {
                    toRet = toRet + ",\n";
                }
            }
        }
        else
        {
            toRet = toRet + "Unknown";
        }
        return toRet;
    }
}
