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.plugin.MojoFailureException;
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, MojoFailureException
    {
        // 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 ) ) );
        }
    }
}