package org.apache.maven.plugin.war;

/*
 * 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 org.apache.maven.artifact.Artifact;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * An overlay is a skeleton WAR added to another WAR project in order to inject a functionality, resources or any other
 * shared component.
 * <p/>
 * Note that a particular WAR dependency can be added multiple times as an overlay with different includes/excludes
 * filter; this allows building a fine grained overwriting policy.
 * <p/>
 * The current project can also be described as an overlay and can not be specified twice. An overlay with no groupId
 * and no artifactId represents the current project.
 *
 * @author Stephane Nicoll
 * @version $Id$
 */
public class Overlay
{

    /**
     * The list of default includes.
     */
    public static final String[] DEFAULT_INCLUDES = new String[] { "**/**" };

    /**
     * The list of default excludes.
     */
    public static final String[] DEFAULT_EXCLUDES = new String[] { "META-INF/MANIFEST.MF" };

    private String id;

    private String groupId;

    private String artifactId;

    private String classifier = null;

    private String[] includes = DEFAULT_INCLUDES;

    private String[] excludes = DEFAULT_EXCLUDES;

    private boolean filtered = false;

    private boolean skip = false;

    private Artifact artifact;

    private String targetPath;

    /** default overlay type is war */
    private String type = "war";

    /**
     * Create instance.
     */
    public Overlay()
    {
        super();
    }

    /**
     * @param groupId {@link #groupId}
     * @param artifactId {@link #artifactId}
     */
    public Overlay( String groupId, String artifactId )
    {
        this();
        this.groupId = groupId;
        this.artifactId = artifactId;
    }

    /**
     * Specify whether this overlay represents the current project or not.
     *
     * @return true if the overlay represents the current project, false otherwise
     */
    public boolean isCurrentProject()
    {
        return ( groupId == null && artifactId == null );
    }

    /**
     * @return {@link Overlay} instance.
     */
    public static Overlay createInstance()
    {
        Overlay overlay = new Overlay();
        overlay.setId( "currentBuild" );
        return overlay;
    }

    // Getters and Setters

    /**
     * @return The id.
     */
    public String getId()
    {
        if ( id == null )
        {
            final StringBuilder sb = new StringBuilder();
            sb.append( getGroupId() ).append( ":" ).append( getArtifactId() );
            if ( getClassifier() != null )
            {
                sb.append( ":" ).append( getClassifier() );
            }
            id = sb.toString();
        }
        return id;
    }

    /**
     * @param id The id.
     */
    public void setId( String id )
    {
        this.id = id;
    }

    /**
     * @return {@link #groupId}
     */
    public String getGroupId()
    {
        return groupId;
    }

    /**
     * @param groupId {@link #groupId}
     */
    public void setGroupId( String groupId )
    {
        this.groupId = groupId;
    }

    /**
     * @return {@link #artifactId}
     */
    public String getArtifactId()
    {
        return artifactId;
    }

    /**
     * @param artifactId {@link #artifactId}
     */
    public void setArtifactId( String artifactId )
    {
        this.artifactId = artifactId;
    }

    /**
     * @return {@link #classifier}
     */
    public String getClassifier()
    {
        return classifier;
    }

    /**
     * @param classifier {@link #classifier}
     */
    public void setClassifier( String classifier )
    {
        this.classifier = classifier;
    }

    /**
     * @return {@link #includes}
     */
    public String[] getIncludes()
    {
        return includes;
    }

    /**
     * @param includes {@link #includes}
     */
    public void setIncludes( String includes )
    {
        this.includes = parse( includes );
    }

    /**
     * @param includes {@link #includes}
     */
    public void setIncludes( String[] includes )
    {
        this.includes = includes;
    }

    /**
     * @return {@link #excludes}
     */
    public String[] getExcludes()
    {
        return excludes;
    }

    /**
     * @param excludes {@link #excludes}
     */
    public void setExcludes( String excludes )
    {
        this.excludes = parse( excludes );
    }

    /**
     * @param excludes {@link #excludes}
     */
    public void setExcludes( String[] excludes )
    {
        this.excludes = excludes;
    }

    /**
     * @return {@link #filtered}
     */
    public boolean isFiltered()
    {
        return filtered;
    }

    /**
     * @param filtered {@link #filtered}
     */
    public void setFiltered( boolean filtered )
    {
        this.filtered = filtered;
    }

    /**
     * @return {@link #skip}
     */
    public boolean shouldSkip()
    {
        return skip;
    }

    /**
     * @param skip {@link #skip}
     */
    public void setSkip( boolean skip )
    {
        this.skip = skip;
    }

    /**
     * @return {@link #artifact}
     */
    public Artifact getArtifact()
    {
        return artifact;
    }

    /**
     * @param artifact {@link #artifact}
     */
    public void setArtifact( Artifact artifact )
    {
        this.artifact = artifact;
    }

    /**
     * @return {@link #targetPath}
     */
    public String getTargetPath()
    {
        return targetPath;
    }

    /**
     * @param targetPath {@link #targetPath}
     */
    public void setTargetPath( String targetPath )
    {
        this.targetPath = targetPath;
    }

    /**
     * @return {@link #type}
     */
    public String getType()
    {
        return type;
    }

    /**
     * @param type {@link #type}
     */
    public void setType( String type )
    {
        this.type = type;
    }

    /**
     * {@inheritDoc}
     */
    public String toString()
    {
        return " id " + getId();
    }

    /**
     * {@inheritDoc}
     */
    public boolean equals( Object o )
    {
        if ( this == o )
        {
            return true;
        }
        if ( o == null || getClass() != o.getClass() )
        {
            return false;
        }

        Overlay overlay = (Overlay) o;

        if ( excludes != null ? !Arrays.equals( excludes, overlay.excludes ) : overlay.excludes != null )
        {
            return false;
        }
        if ( getId() != null ? !getId().equals( overlay.getId() ) : overlay.getId() != null )
        {
            return false;
        }
        if ( includes != null ? !Arrays.equals( includes, overlay.includes ) : overlay.includes != null )
        {
            return false;
        }

        return true;
    }

    /**
     * {@inheritDoc}
     */
    public int hashCode()
    {
        int result;
        result = ( getId() != null ? getId().hashCode() : 0 );
        result = 31 * result + ( includes != null ? includes.hashCode() : 0 );
        result = 31 * result + ( excludes != null ? excludes.hashCode() : 0 );
        return result;
    }

    private String[] parse( String s )
    {
        final List<String> result = new ArrayList<String>();
        if ( s == null )
        {
            return result.toArray( new String[result.size()] );
        }
        else
        {
            String[] tokens = s.split( "," );
            for ( String token : tokens )
            {
                result.add( token.trim() );
            }
            return result.toArray( new String[result.size()] );
        }
    }

}
