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 static org.apache.maven.plugins.war.Overlay.DEFAULT_INCLUDES;
import static org.apache.maven.plugins.war.Overlay.DEFAULT_EXCLUDES;

import org.apache.maven.plugin.testing.stubs.ArtifactStub;
import org.apache.maven.plugins.war.Overlay;
import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
import org.apache.maven.plugins.war.stub.WarArtifactStub;
import org.codehaus.plexus.PlexusTestCase;

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

/**
 * @author Stephane Nicoll
 * @version $Id$
 */
public class OverlayManagerTest
    extends PlexusTestCase
{


    public void testEmptyProject()
        throws Exception
    {
        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        final List<Overlay> overlays = new ArrayList<>();
        try
        {
            final Overlay currentProjectOverlay = Overlay.createInstance();
            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
                                                         currentProjectOverlay );
            assertNotNull( manager.getOverlays() );
            assertEquals( 1, manager.getOverlays().size() );
            assertEquals( currentProjectOverlay, manager.getOverlays().get( 0 ) );
        }
        catch ( InvalidOverlayConfigurationException e )
        {
            e.printStackTrace();
            fail( "Should not have failed to validate a valid overly config " + e.getMessage() );
        }
    }

    public void testAutodetectSimpleOverlay( Overlay currentProjectOverlay )
        throws Exception
    {

        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
        project.addArtifact( first );

        final List<Overlay> overlays = new ArrayList<>();

        try
        {
            final Overlay overlay = currentProjectOverlay;
            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
                                                         overlay );
            assertNotNull( manager.getOverlays() );
            assertEquals( 2, manager.getOverlays().size() );
            assertEquals( overlay, manager.getOverlays().get( 0 ) );
            assertEquals( new DefaultOverlay( first ), manager.getOverlays().get( 1 ) );
        }
        catch ( InvalidOverlayConfigurationException e )
        {
            e.printStackTrace();
            fail( "Should not have failed to validate a valid overlay config " + e.getMessage() );
        }
    }

    public void testSimpleOverlay()
        throws Exception
    {

        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
        project.addArtifact( first );

        final List<Overlay> overlays = new ArrayList<>();
        overlays.add( new DefaultOverlay( first ) );

        try
        {
            final Overlay currentProjectOverlay = Overlay.createInstance();
            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
                                                         currentProjectOverlay );
            assertNotNull( manager.getOverlays() );
            assertEquals( 2, manager.getOverlays().size() );
            assertEquals( Overlay.createInstance(), manager.getOverlays().get( 0 ) );
            assertEquals( overlays.get( 0 ), manager.getOverlays().get( 1 ) );
        }
        catch ( InvalidOverlayConfigurationException e )
        {
            e.printStackTrace();
            fail( "Should not have failed to validate a valid overlay config " + e.getMessage() );
        }
    }

    public void testUnknownOverlay()
        throws Exception
    {

        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
        project.addArtifact( first );

        final List<Overlay> overlays = new ArrayList<>();
        overlays.add( new Overlay( "test", "test-webapp-2" ) );

        try
        {
            final Overlay currentProjectOverlay = Overlay.createInstance();
            new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES, currentProjectOverlay );
            fail( "Should have failed to validate an unknown overlay" );
        }
        catch ( InvalidOverlayConfigurationException e )
        {
            // OK
        }
    }

    public void testCustomCurrentProject()
        throws Exception
    {

        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
        final ArtifactStub second = newWarArtifact( "test", "test-webapp-2" );
        project.addArtifact( first );
        project.addArtifact( second );

        final List<Overlay> overlays = new ArrayList<>();
        overlays.add( new DefaultOverlay( first ) );
        final Overlay currentProjectOverlay = Overlay.createInstance();
        overlays.add( currentProjectOverlay );

        try
        {
            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
                                                         currentProjectOverlay );
            assertNotNull( manager.getOverlays() );
            assertEquals( 3, manager.getOverlays().size() );
            assertEquals( overlays.get( 0 ), manager.getOverlays().get( 0 ) );
            assertEquals( currentProjectOverlay, manager.getOverlays().get( 1 ) );
            assertEquals( new DefaultOverlay( second ), manager.getOverlays().get( 2 ) );

        }
        catch ( InvalidOverlayConfigurationException e )
        {
            e.printStackTrace();
            fail( "Should not have failed to validate a valid overlay config " + e.getMessage() );
        }
    }

    public void testOverlaysWithSameArtifactAndGroupId()
        throws Exception
    {

        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
        final ArtifactStub second = newWarArtifact( "test", "test-webapp", "my-classifier" );

        project.addArtifact( first );
        project.addArtifact( second );

        final List<Overlay> overlays = new ArrayList<>();
        overlays.add( new DefaultOverlay( first ) );
        overlays.add( new DefaultOverlay( second ) );

        try
        {
            final Overlay currentProjectOverlay = Overlay.createInstance();
            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
                                                         currentProjectOverlay );
            assertNotNull( manager.getOverlays() );
            assertEquals( 3, manager.getOverlays().size() );
            assertEquals( currentProjectOverlay, manager.getOverlays().get( 0 ) );
            assertEquals( overlays.get( 0 ), manager.getOverlays().get( 1 ) );
            assertEquals( overlays.get( 1 ), manager.getOverlays().get( 2 ) );

        }
        catch ( InvalidOverlayConfigurationException e )
        {
            e.printStackTrace();
            fail( "Should not have failed to validate a valid overlay config " + e.getMessage() );
        }
    }


    protected ArtifactStub newWarArtifact( String groupId, String artifactId, String classifier )
    {
        final WarArtifactStub a = new WarArtifactStub( getBasedir() );
        a.setGroupId( groupId );
        a.setArtifactId( artifactId );
        if ( classifier != null )
        {
            a.setClassifier( classifier );
        }
        return a;
    }

    protected ArtifactStub newWarArtifact( String groupId, String artifactId )
    {
        return newWarArtifact( groupId, artifactId, null );

    }
}
