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;

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