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.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.ear.output.FileNameMappingFactory;
import org.apache.maven.plugins.ear.util.ArtifactRepository;
import org.codehaus.plexus.util.xml.XMLWriter;

/**
 * A base implementation of an {@link EarModule}.
 * 
 * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
 * @version $Id: AbstractEarModule.java 1645331 2014-12-13 17:31:09Z khmarbaise $
 */
public abstract class AbstractEarModule
    implements EarModule
{

    /**
     * The module element.
     */
    protected static final String MODULE_ELEMENT = "module";

    /**
     * The java module.
     */
    protected static final String JAVA_MODULE = "java";

    /**
     * The alt-dd module.
     */
    protected static final String ALT_DD = "alt-dd";

    private Artifact artifact;

    // Those are set by the configuration

    private String groupId;

    private String artifactId;

    private String classifier;

    /**
     * The bundleDir.
     */
    protected String bundleDir;

    /**
     * The bundleFileName.
     */
    protected String bundleFileName;

    /**
     * excluded by default {@code false}.
     */
    protected Boolean excluded = Boolean.FALSE;

    private String uri;

    /**
     * unpack
     */
    protected Boolean unpack = null;

    /**
     * The alternate deployment descriptor.
     */
    protected String altDeploymentDescriptor;

    private String moduleId;

    // This is injected once the module has been built.

    /**
     * The {@link EarExecutionContext}
     */
    protected EarExecutionContext earExecutionContext;

    /**
     * Empty constructor to be used when the module is built based on the configuration.
     */
    public AbstractEarModule()
    {
    }

    /**
     * Creates an ear module from the artifact.
     * 
     * @param a the artifact
     */
    public AbstractEarModule( Artifact a )
    {
        this.artifact = a;
        this.groupId = a.getGroupId();
        this.artifactId = a.getArtifactId();
        this.classifier = a.getClassifier();
        this.bundleDir = null;
    }

    /**
     * {@inheritDoc}
     */
    public void setEarExecutionContext( EarExecutionContext earExecutionContext )
    {
        this.earExecutionContext = earExecutionContext;
    }

    /** {@inheritDoc} */
    public void resolveArtifact( Set<Artifact> artifacts )
        throws EarPluginException, MojoFailureException
    {
        // If the artifact is already set no need to resolve it
        if ( artifact == null )
        {
            // Make sure that at least the groupId and the artifactId are specified
            if ( groupId == null || artifactId == null )
            {
                throw new MojoFailureException( "Could not resolve artifact[" + groupId + ":" + artifactId + ":"
                    + getType() + "]" );
            }
            final ArtifactRepository ar = earExecutionContext.getArtifactRepository();
            artifact = ar.getUniqueArtifact( groupId, artifactId, getType(), classifier );
            // Artifact has not been found
            if ( artifact == null )
            {
                Set<Artifact> candidates = ar.getArtifacts( groupId, artifactId, getType() );
                if ( candidates.size() > 1 )
                {
                    throw new MojoFailureException( "Artifact[" + this + "] has " + candidates.size()
                        + " candidates, please provide a classifier." );
                }
                else
                {
                    throw new MojoFailureException( "Artifact[" + this + "] is not a dependency of the project." );
                }
            }
        }
    }

    /**
     * @return {@link #artifact}
     */
    public Artifact getArtifact()
    {
        return artifact;
    }

    /**
     * @return {@link #moduleId}
     */
    public String getModuleId()
    {
        return moduleId;
    }

    /**
     * @return Return the URI.
     */
    public String getUri()
    {
        if ( uri == null )
        {
            if ( getBundleDir() == null )
            {
                uri = getBundleFileName();
            }
            else
            {
                uri = getBundleDir() + getBundleFileName();
            }
        }
        return uri;
    }

    /**
     * Returns the artifact's groupId.
     * 
     * @return {@link #groupId}
     */
    public String getGroupId()
    {
        return groupId;
    }

    /**
     * Returns the artifact's Id.
     * 
     * @return {@link #artifactId}
     */
    public String getArtifactId()
    {
        return artifactId;
    }

    /**
     * Returns the artifact's classifier.
     * 
     * @return the artifact classifier
     */
    public String getClassifier()
    {
        return classifier;
    }

    /**
     * Returns the bundle directory. If null, the module is bundled in the root of the EAR.
     * 
     * @return the custom bundle directory
     */
    public String getBundleDir()
    {
        if ( bundleDir != null )
        {
            bundleDir = cleanBundleDir( bundleDir );
        }
        return bundleDir;
    }

    /**
     * Returns the bundle file name. If null, the artifact's file name is returned.
     * 
     * @return the bundle file name
     */
    public String getBundleFileName()
    {
        if ( bundleFileName == null )
        {
            bundleFileName = earExecutionContext.getFileNameMapping().mapFileName( artifact );
        }
        return bundleFileName;
    }

    /**
     * Based on MEAR-189 we need to get back
     * the original file name under any circumstances.
     * 
     * @return The original file name.
     */
    public String getOriginalBundleFileName()
    {
        return FileNameMappingFactory.getDefaultFileNameMapping().mapFileName( artifact );
    }

    /**
     * The alt-dd element specifies an optional URI to the post-assembly version of the deployment descriptor file for a
     * particular Java EE module. The URI must specify the full pathname of the deployment descriptor file relative to
     * the application's root directory.
     * 
     * @return the alternative deployment descriptor for this module
     */
    public String getAltDeploymentDescriptor()
    {
        return altDeploymentDescriptor;
    }

    /**
     * Specify whether this module should be excluded or not.
     * 
     * @return true if this module should be skipped, false otherwise
     */
    public boolean isExcluded()
    {
        return excluded;
    }

    /**
     * @return {@link #unpack}
     */
    public Boolean shouldUnpack()
    {
        return unpack;
    }

    /**
     * Writes the alternative deployment descriptor if necessary.
     * 
     * @param writer the writer to use
     * @param version the java EE version in use
     */
    protected void writeAltDeploymentDescriptor( XMLWriter writer, String version )
    {
        if ( getAltDeploymentDescriptor() != null )
        {
            writer.startElement( ALT_DD );
            writer.writeText( getAltDeploymentDescriptor() );
            writer.endElement();
        }
    }

    /**
     * Starts a new {@link #MODULE_ELEMENT} on the specified writer, possibly including an id attribute.
     * 
     * @param writer the XML writer.
     * @param generateId whether an id should be generated
     */
    protected void startModuleElement( XMLWriter writer, Boolean generateId )
    {
        writer.startElement( MODULE_ELEMENT );

        // If a moduleId is specified, always include it
        if ( getModuleId() != null )
        {
            writer.addAttribute( "id", getModuleId() );
        }
        else if ( generateId )
        {
            // No module id was specified but one should be generated.
            Artifact theArtifact = getArtifact();
            String generatedId =
                theArtifact.getType().toUpperCase() + "_" + theArtifact.getGroupId() + "."
                    + theArtifact.getArtifactId();
            if ( null != theArtifact.getClassifier() && theArtifact.getClassifier().trim().length() > 0 )
            {
                generatedId += "-" + theArtifact.getClassifier().trim();
            }
            writer.addAttribute( "id", generatedId );
        }
    }

    /**
     * {@inheritDoc}
     */
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        sb.append( getType() ).append( ":" ).append( groupId ).append( ":" ).append( artifactId );
        if ( classifier != null )
        {
            sb.append( ":" ).append( classifier );
        }
        if ( artifact != null )
        {
            sb.append( ":" ).append( artifact.getVersion() );
        }
        return sb.toString();
    }

    /**
     * Cleans the bundle directory so that it might be used properly.
     * 
     * @param bundleDir the bundle directory to clean
     * @return the cleaned bundle directory
     */
    static String cleanBundleDir( String bundleDir )
    {
        if ( bundleDir == null )
        {
            return null;
        }

        // Using slashes
        bundleDir = bundleDir.replace( '\\', '/' );

        // Remove '/' prefix if any so that directory is a relative path
        if ( bundleDir.startsWith( "/" ) )
        {
            bundleDir = bundleDir.substring( 1, bundleDir.length() );
        }

        if ( bundleDir.length() > 0 && !bundleDir.endsWith( "/" ) )
        {
            // Adding '/' suffix to specify a directory structure if it is not empty
            bundleDir = bundleDir + "/";
        }

        return bundleDir;
    }

    /**
     * Specify if the objects are both null or both equal.
     * 
     * @param first the first object
     * @param second the second object
     * @return true if parameters are either both null or equal
     */
    static boolean areNullOrEqual( Object first, Object second )
    {
        if ( first != null )
        {
            return first.equals( second );
        }
        else
        {
            return second == null;
        }
    }

    /**
     * Sets the URI of the module explicitly for testing purposes.
     * 
     * @param uri the uri
     */
    void setUri( String uri )
    {
        this.uri = uri;

    }

    /**
     * @return always {@code true}
     */
    public boolean changeManifestClasspath()
    {
        return true;
    }

    /**
     * @return always {@code null}
     */
    public String getLibDir()
    {
        return null;
    }
}
