/* ==========================================================================
 * Copyright 2003-2004 Mevenide Team
 *
 * 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.
 * =========================================================================
 */
package org.netbeans.nbm;

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 <a href="mailto:mkleint@codehaus.org">Milos Kleint</a>
 */
@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;

    /**
     * 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 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 );
                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 );
        }
    }

    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;
    }
}
