package org.apache.maven.plugins.ear;

/*
 * 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.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.plugin.MojoExecutionException;
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.plugins.ear.util.JavaEEVersion;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.Interpolator;
import org.codehaus.plexus.interpolation.MapBasedValueSource;
import org.codehaus.plexus.interpolation.StringSearchInterpolator;
import org.codehaus.plexus.interpolation.ValueSource;
import org.codehaus.plexus.util.FileUtils;

/**
 * Generates the EAR deployment descriptor file(s).
 * 
 * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
 */
@Mojo( name = "generate-application-xml",
       defaultPhase = LifecyclePhase.GENERATE_RESOURCES,
       threadSafe = true,
       requiresDependencyResolution = ResolutionScope.TEST )
public class GenerateApplicationXmlMojo
    extends AbstractEarMojo
{

    /**
     * The DEFAULT library folder.
     */
    public static final String DEFAULT = "DEFAULT";

    /**
     * The empty folder.
     */
    public static final String EMPTY = "EMPTY";

    /**
     * The NONE not existent folder.
     */
    public static final String NONE = "NONE";

    /**
     * Whether the application.xml should be generated or not.
     */
    @Parameter( defaultValue = "true" )
    private Boolean generateApplicationXml = Boolean.TRUE;

    /**
     * Whether a module ID should be generated if none is specified.
     */
    @Parameter( defaultValue = "false" )
    private Boolean generateModuleId = Boolean.FALSE;

    /**
     * Application name of the application to be used when the application.xml file is auto-generated. Since JavaEE6.
     */
    @Parameter
    private String applicationName;

    /**
     * Display name of the application to be used when the application.xml file is auto-generated.
     */
    @Parameter( defaultValue = "${project.artifactId}" )
    private String displayName;

    /**
     * Description of the application to be used when the application.xml file is auto-generated.
     */
    @Parameter( defaultValue = "${project.description}" )
    private String description;

    /**
     * Defines how the {@code library-directory} element should be written in the application.xml file.
     * <p/>
     * Three special values can be set:
     * <ul>
     * <li><code>DEFAULT</code> (default) generates a {@code library-directory} element with the value of the
     * {@code defaultLibBundleDir} parameter</li>
     * <li><code>EMPTY</code> generates an empty {@code library-directory} element. Per spec, this disables the
     * scanning of jar files in the {@code lib} directory of the ear file</li>
     * <li><code>NONE</code> does not write the library-directory element at all. A corner case that can be used in
     * Oracle Weblogic to delegate the classloading to the container</li>
     * </ul>
     * <p/>
     * Since JavaEE5.
     */
    @Parameter( defaultValue = DEFAULT )
    private String libraryDirectoryMode;

    /**
     * Defines the value of the initialize in order element to be used when the application.xml file is auto-generated.
     * When set to true, modules must be initialized in the order they're listed in this deployment descriptor, with the
     * exception of application client modules, which can be initialized in any order. If initialize-in-order is not set
     * or set to false, the order of initialization is unspecified and may be product-dependent. Since JavaEE6.
     */
    @Parameter
    private Boolean initializeInOrder;

    /**
     * Defines the application id used when generating the deployment descriptor.
     * 
     * @since 2.9
     */
    @Parameter
    private String applicationId;

    /**
     * The security-roles to be added to the auto-generated application.xml file.
     */
    @Parameter
    private PlexusConfiguration security;

    /**
     * The env-entries to be added to the auto-generated application.xml file. Since JavaEE6.
     */
    @Parameter( alias = "env-entries" )
    private PlexusConfiguration envEntries;

    /**
     * The {@code ejb-ref} entries.
     */
    @Parameter( alias = "ejb-refs" )
    private PlexusConfiguration ejbRefs;

    /**
     * The {@code resource-ref} entries.
     */
    @Parameter
    private PlexusConfiguration resourceRefs;

    /**
     * {@inheritDoc}
     */
    public void execute()
        throws MojoExecutionException
    {
        // Initializes ear modules
        super.execute();

        // Handle application.xml
        if ( !generateApplicationXml )
        {
            getLog().debug( "Generation of application.xml is disabled" );
        }
        else
        {
            final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion( version );

            // Generate deployment descriptor and copy it to the build directory
            getLog().info( "Generating application.xml" );
            try
            {
                generateStandardDeploymentDescriptor( javaEEVersion );
            }
            catch ( EarPluginException e )
            {
                throw new MojoExecutionException( "Failed to generate application.xml", e );
            }

            try
            {
                FileUtils.copyFileToDirectory( new File( generatedDescriptorLocation, "application.xml" ),
                                               new File( getWorkDirectory(), "META-INF" ) );
            }
            catch ( IOException e )
            {
                throw new MojoExecutionException( "Unable to copy application.xml to final destination", e );
            }
        }

        // Handle jboss-app.xml
        if ( getJbossConfiguration() == null )
        {
            getLog().debug( "Generation of jboss-app.xml is disabled" );
        }
        else
        {
            // Generate deployment descriptor and copy it to the build directory
            getLog().info( "Generating jboss-app.xml" );
            try
            {
                generateJbossDeploymentDescriptor();
            }
            catch ( EarPluginException e )
            {
                throw new MojoExecutionException( "Failed to generate jboss-app.xml", e );
            }

            try
            {
                FileUtils.copyFileToDirectory( new File( generatedDescriptorLocation, "jboss-app.xml" ),
                                               new File( getWorkDirectory(), "META-INF" ) );
            }
            catch ( IOException e )
            {
                throw new MojoExecutionException( "Unable to copy jboss-app.xml to final destination", e );
            }
        }
    }

    /**
     * Generates the deployment descriptor.
     * 
     * @param javaEEVersion {@link JavaEEVersion}
     * @throws EarPluginException if the configuration is invalid
     */
    protected void generateStandardDeploymentDescriptor( JavaEEVersion javaEEVersion )
        throws EarPluginException
    {
        File outputDir = new File( generatedDescriptorLocation );
        if ( !outputDir.exists() )
        {
            if ( !outputDir.mkdirs() )
            {
                throw new EarPluginException( "Error creating " + outputDir );
            }
        }

        File descriptor = new File( outputDir, "application.xml" );

        final ApplicationXmlWriter writer = new ApplicationXmlWriter( javaEEVersion, encoding, generateModuleId );
        final ApplicationXmlWriterContext context =
            new ApplicationXmlWriterContext( descriptor, getModules(), buildSecurityRoles(), buildEnvEntries(),
                                             buildEjbEntries(), buildResourceRefs(), displayName, description,
                                             getActualLibraryDirectory(), applicationName,
                                             initializeInOrder ).setApplicationId( applicationId );
        writer.write( context );
    }

    /**
     * Generates the JBoss deployment descriptor.
     * 
     * @throws EarPluginException if the configuration is invalid
     */
    protected void generateJbossDeploymentDescriptor()
        throws EarPluginException
    {
        File outputDir = new File( generatedDescriptorLocation );
        if ( !outputDir.exists() )
        {
            if ( !outputDir.mkdirs() )
            {
                throw new EarPluginException( "Error creating " + outputDir );
            }
        }

        File descriptor = new File( outputDir, "jboss-app.xml" );

        JbossAppXmlWriter writer = new JbossAppXmlWriter( encoding );
        writer.write( descriptor, getJbossConfiguration(), getModules() );
    }

    /**
     * Builds the security roles based on the configuration.
     * 
     * @return a list of SecurityRole object(s)
     * @throws EarPluginException if the configuration is invalid
     */
    private List<SecurityRole> buildSecurityRoles()
        throws EarPluginException
    {
        final List<SecurityRole> result = new ArrayList<SecurityRole>();
        if ( security == null )
        {
            return result;
        }
        final PlexusConfiguration[] securityRoles = security.getChildren( SecurityRole.SECURITY_ROLE );

        for ( PlexusConfiguration securityRole : securityRoles )
        {
            final String id = securityRole.getAttribute( SecurityRole.ID_ATTRIBUTE );
            final String childRoleName = securityRole.getChild( SecurityRole.ROLE_NAME ).getValue();
            final String childRoleNameId =
                securityRole.getChild( SecurityRole.ROLE_NAME ).getAttribute( SecurityRole.ID_ATTRIBUTE );
            final String childDescription = securityRole.getChild( SecurityRole.DESCRIPTION ).getValue();
            final String childDescriptionId =
                securityRole.getChild( SecurityRole.DESCRIPTION ).getAttribute( SecurityRole.ID_ATTRIBUTE );

            if ( childRoleName == null )
            {
                throw new EarPluginException( "Invalid security-role configuration, role-name could not be null." );
            }
            else
            {
                result.add( new SecurityRole( childRoleName, childRoleNameId, id, childDescription,
                                              childDescriptionId ) );
            }
        }
        return result;
    }

    /**
     * This help method was needed otherwise the interpolate method of interpolator will make an empty string of a
     * {@code null} element which results in supplemental elements for env-entry.
     * 
     * @param interpolator The interpolator
     * @param element The element
     * @return The interpolated elements.
     * @throws InterpolationException in case of an error.
     */
    private String interpolate( Interpolator interpolator, String element )
        throws InterpolationException
    {
        if ( element == null )
        {
            return element;
        }
        else
        {
            return interpolator.interpolate( element );
        }
    }

    /**
     * Builds the env-entries based on the configuration.
     * 
     * @return a list of EnvEntry object(s)
     * @throws EarPluginException if the configuration is invalid
     */
    private List<EnvEntry> buildEnvEntries()
        throws EarPluginException
    {
        final List<EnvEntry> result = new ArrayList<EnvEntry>();
        if ( envEntries == null )
        {
            return result;
        }
        try
        {
            StringSearchInterpolator ssi = new StringSearchInterpolator();
            ValueSource vs = new MapBasedValueSource( project.getProperties() );
            ssi.addValueSource( vs );

            final PlexusConfiguration[] allEnvEntries = envEntries.getChildren( EnvEntry.ENV_ENTRY );

            getLog().debug( "buildEnvEntries: allEnvEntries:" + allEnvEntries );
            getLog().debug( "buildEnvEntries: allEnvEntries size:" + allEnvEntries.length );
            for ( PlexusConfiguration envEntry : allEnvEntries )
            {
                final String childDescription =
                    interpolate( ssi, envEntry.getChild( EnvEntry.DESCRIPTION ).getValue() );
                final String childEnvEntryName =
                    interpolate( ssi, envEntry.getChild( EnvEntry.ENV_ENTRY_NAME ).getValue() );
                final String childEnvEntryType =
                    interpolate( ssi, envEntry.getChild( EnvEntry.ENV_ENTRY_TYPE ).getValue() );
                final String childEnvEntryValue =
                    interpolate( ssi, envEntry.getChild( EnvEntry.ENV_ENTRY_VALUE ).getValue() );
                final String childEnvLookupNameValue =
                    interpolate( ssi, envEntry.getChild( EnvEntry.ENV_LOOKUP_NAME ).getValue() );

                try
                {
                    result.add( new EnvEntry( childDescription, childEnvEntryName, childEnvEntryType,
                                              childEnvEntryValue, childEnvLookupNameValue ) );
                }
                catch ( IllegalArgumentException e )
                {
                    throw new EarPluginException( "Invalid env-entry [" + envEntry + "]", e );
                }
            }
            return result;
        }
        catch ( InterpolationException e )
        {
            throw new EarPluginException( "Interpolation exception:", e );
        }

    }

    /**
     * Builds the ejb-ref based on the configuration.
     * 
     * @return a list of EjbRef object(s)
     * @throws EarPluginException if the configuration is invalid
     */
    private List<EjbRef> buildEjbEntries()
        throws EarPluginException
    {
        final List<EjbRef> result = new ArrayList<EjbRef>();
        if ( ejbRefs == null )
        {
            return result;
        }
        try
        {
            StringSearchInterpolator ssi = new StringSearchInterpolator();
            ValueSource vs = new MapBasedValueSource( project.getProperties() );
            ssi.addValueSource( vs );

            final PlexusConfiguration[] allEjbEntries = ejbRefs.getChildren( EjbRef.EJB_REF );

            for ( PlexusConfiguration ejbEntry : allEjbEntries )
            {
                final String childDescription =
                    interpolate( ssi, ejbEntry.getChild( EnvEntry.DESCRIPTION ).getValue() );
                final String childEjbEntryName = interpolate( ssi, ejbEntry.getChild( EjbRef.EJB_NAME ).getValue() );
                final String childEjbEntryType = interpolate( ssi, ejbEntry.getChild( EjbRef.EJB_TYPE ).getValue() );
                final String childEjbLookupNameValue =
                    interpolate( ssi, ejbEntry.getChild( EjbRef.EJB_LOOKUP_NAME ).getValue() );

                try
                {
                    result.add( new EjbRef( childDescription, childEjbEntryName, childEjbEntryType,
                                            childEjbLookupNameValue ) );
                }
                catch ( IllegalArgumentException e )
                {
                    throw new EarPluginException( "Invalid ejb-ref [" + ejbEntry + "]", e );
                }
            }
            return result;
        }
        catch ( InterpolationException e )
        {
            throw new EarPluginException( "Interpolation exception:", e );
        }

    }

    /**
     * Builds the <code>resource-ref</code> based on the configuration.
     * 
     * @return a list of ResourceRef object(s)
     * @throws EarPluginException if the configuration is invalid
     */
    private List<ResourceRef> buildResourceRefs()
        throws EarPluginException
    {
        final List<ResourceRef> result = new ArrayList<ResourceRef>();
        if ( resourceRefs == null )
        {
            return result;
        }
        try
        {
            getLog().debug( "Resources found" );
            StringSearchInterpolator ssi = new StringSearchInterpolator();
            ValueSource vs = new MapBasedValueSource( project.getProperties() );
            ssi.addValueSource( vs );

            // TODO: Check if this is a good idea hard code that here? Better idea?
            final PlexusConfiguration[] allResourceRefEntries = resourceRefs.getChildren( "resourceRef" );

            getLog().debug( "allResourceRefEntries: " + allResourceRefEntries );
            getLog().debug( "allResourceRefEntries length: " + allResourceRefEntries.length );
            for ( PlexusConfiguration resEntry : allResourceRefEntries )
            {
                getLog().debug( "Resources resEntry:" + resEntry.getName() );

                final String childResRefName =
                    interpolate( ssi, resEntry.getChild( ResourceRef.RESOURCE_REF_NAME ).getValue() );
                final String childResType =
                    interpolate( ssi, resEntry.getChild( ResourceRef.RESOURCE_TYPE ).getValue() );
                final String childResRefAuth =
                    interpolate( ssi, resEntry.getChild( ResourceRef.RESOURCE_AUTH ).getValue() );
                final String childResRefLookupName =
                    interpolate( ssi, resEntry.getChild( ResourceRef.LOOKUP_NAME ).getValue() );

                try
                {
                    result.add(
                            new ResourceRef( childResRefName, childResType, childResRefAuth, childResRefLookupName ) );
                }
                catch ( IllegalArgumentException e )
                {
                    throw new EarPluginException( "Invalid resource-ref [" + resEntry + "]", e );
                }
            }
            return result;
        }
        catch ( InterpolationException e )
        {
            throw new EarPluginException( "Interpolation exception:", e );
        }

    }

    /**
     * Returns the value to use for the {@code library-directory} element, based on the library directory mode.
     */
    private String getActualLibraryDirectory()
        throws EarPluginException
    {
        final String mode = libraryDirectoryMode == null ? DEFAULT : libraryDirectoryMode.toUpperCase();

        if ( DEFAULT.equals( mode ) )
        {
            return defaultLibBundleDir;
        }
        else if ( EMPTY.equals( mode ) )
        {
            return "";
        }
        else if ( NONE.equals( mode ) )
        {
            return null;
        }
        else
        {
            throw new EarPluginException( "Unsupported library directory mode [" + libraryDirectoryMode
                + "] Supported modes " + ( Arrays.asList( DEFAULT, EMPTY, NONE ) ) );
        }
    }
}