/* ==========================================================================
 * 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.codehaus.mojo.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;
    }
}
