package org.apache.maven.plugins.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;

/**
 * <p>
 * An overlay is a skeleton WAR added to another WAR project in order to inject a functionality, resources or any other
 * shared component.</p>
 * 
 * <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>
 * 
 * <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.</p>
 *
 * @author Stephane Nicoll
 */
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;
    }

    @Override
    public String toString()
    {
        return " id " + getId();
    }

    @Override
    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;
    }

    @Override
    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<>();
        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()] );
        }
    }

}
