package org.apache.maven.plugins.war.overlay;

/*
 * 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.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.plugins.war.Overlay;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.StringUtils;

/**
 * Manages the overlays.
 *
 * @author Stephane Nicoll
 * @version $Id$
 */
public class OverlayManager
{
    private final List<Overlay> overlays;

    private final MavenProject project;

    private final List<Artifact> artifactsOverlays;

    /**
     * Creates a manager with the specified overlays.
     * 
     * Note that the list is potentially updated by the manager so a new list is created based on the overlays.
     *
     * @param overlays the overlays
     * @param project the maven project
     * @param defaultIncludes the default includes to use
     * @param defaultExcludes the default excludes to use
     * @param currentProjectOverlay the overlay for the current project
     * @throws InvalidOverlayConfigurationException if the config is invalid
     */
    public OverlayManager( List<Overlay> overlays, MavenProject project, String[] defaultIncludes,
                           String[] defaultExcludes, Overlay currentProjectOverlay )
        throws InvalidOverlayConfigurationException
    {
        this.overlays = new ArrayList<Overlay>();
        if ( overlays != null )
        {
            this.overlays.addAll( overlays );
        }
        this.project = project;

        this.artifactsOverlays = getOverlaysAsArtifacts();

        // Initialize
        initialize( defaultIncludes, defaultExcludes, currentProjectOverlay );

    }

    /**
     * Returns the resolved overlays.
     *
     * @return the overlays
     */
    public List<Overlay> getOverlays()
    {
        return overlays;
    }

    /**
     * Returns the id of the resolved overlays.
     *
     * @return the overlay ids
     */
    public List<String> getOverlayIds()
    {
        final List<String> result = new ArrayList<String>();
        for ( Overlay overlay : overlays )
        {
            result.add( overlay.getId() );
        }
        return result;

    }

    /**
     * Initializes the manager and validates the overlays configuration.
     *
     * @param defaultIncludes the default includes to use
     * @param defaultExcludes the default excludes to use
     * @param currentProjectOverlay the overlay for the current project
     * @throws InvalidOverlayConfigurationException if the configuration is invalid
     */
    void initialize( String[] defaultIncludes, String[] defaultExcludes, Overlay currentProjectOverlay )
        throws InvalidOverlayConfigurationException
    {

        // Build the list of configured artifacts and makes sure that each overlay
        // refer to a valid artifact
        final List<Artifact> configuredWarArtifacts = new ArrayList<Artifact>();
        final ListIterator<Overlay> it = overlays.listIterator();
        while ( it.hasNext() )
        {
            Overlay overlay = it.next();
            if ( overlay == null )
            {
                throw new InvalidOverlayConfigurationException( "overlay could not be null." );
            }
            // If it's the current project, return the project instance
            if ( overlay.isCurrentProject() )
            {
                overlay = currentProjectOverlay;
                it.set( overlay );
            }
            // default includes/excludes - only if the overlay uses the default settings
            if ( Arrays.equals( Overlay.DEFAULT_INCLUDES, overlay.getIncludes() )
                && Arrays.equals( Overlay.DEFAULT_EXCLUDES, overlay.getExcludes() ) )
            {
                overlay.setIncludes( defaultIncludes );
                overlay.setExcludes( defaultExcludes );
            }

            final Artifact artifact = getAssociatedArtifact( overlay );
            if ( artifact != null )
            {
                configuredWarArtifacts.add( artifact );
                overlay.setArtifact( artifact );
            }
        }

        // Build the list of missing overlays
        for ( Artifact artifact : artifactsOverlays )
        {
            if ( !configuredWarArtifacts.contains( artifact ) )
            {
                // Add a default overlay for the given artifact which will be applied after
                // the ones that have been configured
                overlays.add( new DefaultOverlay( artifact, defaultIncludes, defaultExcludes ) );
            }
        }

        // Final validation, make sure that the current project is in there. Otherwise add it first
        for ( Overlay overlay : overlays )
        {
            if ( overlay.equals( currentProjectOverlay ) )
            {
                return;
            }
        }
        overlays.add( 0, currentProjectOverlay );
    }

    /**
     * Returns the Artifact associated to the specified overlay.
     * 
     * If the overlay defines the current project, <tt>null</tt> is returned. If no artifact could not be found for the
     * overlay a InvalidOverlayConfigurationException is thrown.
     *
     * @param overlay an overlay
     * @return the artifact associated to the overlay
     * @throws org.apache.maven.plugins.war.overlay.InvalidOverlayConfigurationException if the overlay does not have an
     *             associated artifact
     */
    Artifact getAssociatedArtifact( final Overlay overlay )
        throws InvalidOverlayConfigurationException
    {
        if ( overlay.isCurrentProject() )
        {
            return null;
        }

        for ( Artifact artifact : artifactsOverlays )
        {
            // Handle classifier dependencies properly (clash management)
            if ( compareOverlayWithArtifact( overlay, artifact ) )
            {
                return artifact;
            }
        }

        // maybe its a project dependencies zip or an other type
        Set<Artifact> projectArtifacts = this.project.getDependencyArtifacts();
        if ( projectArtifacts != null )
        {
            for ( Artifact artifact : projectArtifacts )
            {
                if ( compareOverlayWithArtifact( overlay, artifact ) )
                {
                    return artifact;
                }
            }
        }
        // CHECKSTYLE_OFF: LineLength
        throw new InvalidOverlayConfigurationException( "overlay [" + overlay + "] is not a dependency of the project." );
        // CHECKSTYLE_ON: LineLength

    }

    /**
     * Compare groupId && artifactId && type && classifier.
     *
     * @param overlay the overlay
     * @param artifact the artifact
     * @return boolean true if equals
     */
    private boolean compareOverlayWithArtifact( Overlay overlay, Artifact artifact )
    {
        return ( StringUtils.equals( overlay.getGroupId(), artifact.getGroupId() )
            && StringUtils.equals( overlay.getArtifactId(), artifact.getArtifactId() )
            && StringUtils.equals( overlay.getType(), artifact.getType() )
        // MWAR-241 Make sure to treat null and "" as equal when comparing the classifier
        && StringUtils.equals( StringUtils.defaultString( overlay.getClassifier() ),
                               StringUtils.defaultString( artifact.getClassifier() ) ) );
    }

    /**
     * Returns a list of WAR {@link org.apache.maven.artifact.Artifact} describing the overlays of the current project.
     *
     * @return the overlays as artifacts objects
     */
    private List<Artifact> getOverlaysAsArtifacts()
    {
        ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
        final Set<Artifact> artifacts = project.getArtifacts();

        final List<Artifact> result = new ArrayList<Artifact>();
        for ( Artifact artifact : artifacts )
        {
            if ( !artifact.isOptional() && filter.include( artifact ) && ( "war".equals( artifact.getType() ) ) )
            {
                result.add( artifact );
            }
        }
        return result;
    }
}
