package org.apache.maven.plugins.dependency.analyze;

/*
 * 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.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import junit.framework.TestCase;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.Exclusion;
import org.apache.maven.plugins.dependency.analyze.AnalyzeDepMgt;
import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory;
import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub;
import org.apache.maven.project.MavenProject;

public class TestAnalyzeDepMgt
    extends TestCase
{

    AnalyzeDepMgt mojo;

    DependencyArtifactStubFactory stubFactory;

    Dependency exclusion;

    Exclusion ex;

    Artifact exclusionArtifact;

    DependencyManagement depMgt;

    DependencyManagement depMgtNoExclusions;

    protected void setUp()
        throws Exception
    {

        mojo = new AnalyzeDepMgt();
        MavenProject project = new DependencyProjectStub();

        stubFactory = new DependencyArtifactStubFactory( new File( "" ), false );

        Set<Artifact> allArtifacts = stubFactory.getMixedArtifacts();
        Set<Artifact> directArtifacts = stubFactory.getClassifiedArtifacts();

        exclusionArtifact = stubFactory.getReleaseArtifact();
        directArtifacts.add( exclusionArtifact );
        ex = new Exclusion();
        ex.setArtifactId( exclusionArtifact.getArtifactId() );
        ex.setGroupId( exclusionArtifact.getGroupId() );

        exclusion = new Dependency();
        exclusion.setArtifactId( exclusionArtifact.getArtifactId() );
        exclusion.setGroupId( exclusionArtifact.getGroupId() );
        exclusion.setType( exclusionArtifact.getType() );
        exclusion.setClassifier( "" );
        exclusion.setVersion( "3.0" );

        exclusion.addExclusion( ex );
        List<Dependency> list = new ArrayList<Dependency>();
        list.add( exclusion );

        depMgt = new DependencyManagement();
        depMgt.setDependencies( list );

        project.setArtifacts( allArtifacts );
        project.setDependencyArtifacts( directArtifacts );

        mojo.setProject( project );

    }

    public void testGetManagementKey()
        throws IOException
    {
        Dependency dep = new Dependency();
        dep.setArtifactId( "artifact" );
        dep.setClassifier( "class" );
        dep.setGroupId( "group" );
        dep.setType( "type" );

        // version isn't used in the key, it can be different
        dep.setVersion( "1.1" );

        Artifact artifact =
            stubFactory.createArtifact( "group", "artifact", "1.0", Artifact.SCOPE_COMPILE, "type", "class" );

        // basic case ok
        assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );

        // now change each one and make sure it fails, then set it back and make
        // sure it's ok before
        // testing the next one
        dep.setType( "t" );
        assertFalse( dep.getManagementKey().equals( mojo.getArtifactManagementKey( artifact ) ) );

        dep.setType( "type" );
        assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );

        dep.setArtifactId( "a" );
        assertFalse( dep.getManagementKey().equals( mojo.getArtifactManagementKey( artifact ) ) );

        dep.setArtifactId( "artifact" );
        assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );

        dep.setClassifier( "c" );
        assertFalse( dep.getManagementKey().equals( mojo.getArtifactManagementKey( artifact ) ) );

        dep.setClassifier( "class" );
        assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );

        dep.setGroupId( "g" );
        assertFalse( dep.getManagementKey().equals( mojo.getArtifactManagementKey( artifact ) ) );

        dep.setGroupId( "group" );
        dep.setClassifier( null );
        artifact = stubFactory.createArtifact( "group", "artifact", "1.0", Artifact.SCOPE_COMPILE, "type", null );
        assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );

        dep.setClassifier( "" );
        artifact = stubFactory.createArtifact( "group", "artifact", "1.0", Artifact.SCOPE_COMPILE, "type", "" );
        assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );
    }

    public void testAddExclusions()
    {

        assertEquals( 0, mojo.addExclusions( null ).size() );

        List<Exclusion> list = new ArrayList<Exclusion>();
        list.add( ex );
        Map<String, Exclusion> map = mojo.addExclusions( list );

        assertEquals( 1, map.size() );
        assertTrue( map.containsKey( mojo.getExclusionKey( ex ) ) );
        assertSame( ex, map.get( mojo.getExclusionKey( ex ) ) );
    }

    public void testGetExclusionErrors()
    {
        List<Exclusion> list = new ArrayList<Exclusion>();
        list.add( ex );

        // already tested this method so I can trust it.
        Map<String, Exclusion> map = mojo.addExclusions( list );

        List<Artifact> l = mojo.getExclusionErrors( map, mojo.getProject().getArtifacts() );

        assertEquals( 1, l.size() );

        assertEquals( mojo.getExclusionKey( ex ), mojo.getExclusionKey( l.get( 0 ) ) );
    }

    public void testGetMismatch()
        throws IOException
    {
        Map<String, Dependency> depMgtMap = new HashMap<String, Dependency>();

        depMgtMap.put( exclusion.getManagementKey(), exclusion );

        Map<Artifact, Dependency> results = mojo.getMismatch( depMgtMap, mojo.getProject().getArtifacts() );

        assertEquals( 1, results.size() );
        // the release artifact is used to create the exclusion
        assertTrue( results.containsKey( stubFactory.getReleaseArtifact() ) );
        assertSame( exclusion, results.get( stubFactory.getReleaseArtifact() ) );
    }

    public void testMojo()
        throws IOException
    {
        mojo.setIgnoreDirect( false );
        try
        {
            // test with nothing in depMgt
            mojo.execute();
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "Caught Unexpected Exception:" + e.getLocalizedMessage() );
        }

        try
        {
            DependencyProjectStub project = (DependencyProjectStub) mojo.getProject();
            project.setDependencyManagement( depMgt );
            // test with exclusion
            mojo.execute();
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "Caught Unexpected Exception:" + e.getLocalizedMessage() );
        }

        try
        {
            DependencyProjectStub project = (DependencyProjectStub) mojo.getProject();
            project.setDependencyManagement( depMgt );
            // test with exclusion
            mojo.setFailBuild( true );
            mojo.execute();
            fail( "Expected exception to fail the build." );
        }
        catch ( Exception e )
        {
            System.out.println( "Caught Expected Exception:" + e.getLocalizedMessage() );
        }

        try
        {
            DependencyProjectStub project = (DependencyProjectStub) mojo.getProject();
            project.setDependencyManagement( depMgt );
            // test with exclusion
            mojo.setFailBuild( true );
            mojo.setIgnoreDirect( true );
            mojo.execute();
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "Caught Unexpected Exception:" + e.getLocalizedMessage() );
        }
    }
}
