package org.apache.maven.shared.artifact.filter.resolve.transform;

/*
 * 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.junit.Assert.assertEquals;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.testing.ArtifactStubFactory;
import org.apache.maven.shared.artifact.filter.resolve.Node;
import org.eclipse.aether.graph.DependencyNode;
import org.junit.Test;

public class ArtifactIncludeNodeTest
{
    private ArtifactStubFactory artifactFactory = new ArtifactStubFactory();

    @Test
    public void testGAV() throws Exception
    {
        Node node = new ArtifactIncludeNode( newArtifact( "g:a:v", null ) );

        Dependency dependency = node.getDependency();

        assertEquals( "g", dependency.getGroupId() );
        assertEquals( "a", dependency.getArtifactId() );
        assertEquals( "v", dependency.getVersion() );
        assertEquals( "", dependency.getClassifier() );
        // This is different compared to AetherNodes. Here it's based on artifact, which in the end always has a type.
        assertEquals( "jar", dependency.getType() );
    }

    @Test
    public void testClassifier() throws Exception
    {
        Node node = new ArtifactIncludeNode( newArtifact( "g:a::c:v", null ) );

        Dependency dependency = node.getDependency();

        assertEquals( "g", dependency.getGroupId() );
        assertEquals( "a", dependency.getArtifactId() );
        assertEquals( "v", dependency.getVersion() );
        assertEquals( "c", dependency.getClassifier() );
        // empty type stays empty type when using ArtifactStubFactory
        assertEquals( "", dependency.getType() );
    }

    @Test
    public void testType() throws Exception
    {
        Node node = new ArtifactIncludeNode( newArtifact( "g:a:pom:v", null ) );

        Dependency dependency = node.getDependency();

        assertEquals( "g", dependency.getGroupId() );
        assertEquals( "a", dependency.getArtifactId() );
        assertEquals( "v", dependency.getVersion() );
        assertEquals( null, dependency.getClassifier() );
        assertEquals( "pom", dependency.getType() );
    }

    @Test
    public void testScope() throws Exception
    {
        Node node = new ArtifactIncludeNode( newArtifact( "g:a:v", "s" ) );

        Dependency dependency = node.getDependency();

        assertEquals( "g", dependency.getGroupId() );
        assertEquals( "a", dependency.getArtifactId() );
        assertEquals( "v", dependency.getVersion() );
        assertEquals( "", dependency.getClassifier() );
        assertEquals( "jar", dependency.getType() );
        assertEquals( "s", dependency.getScope() );
    }

    @Test
    public void testOptional() throws Exception
    {
        Node node = new ArtifactIncludeNode( newArtifact( "g:a:pom:v", null, null ) );
        
        assertEquals( "false", node.getDependency().getOptional()  );
        assertEquals( false, node.getDependency().isOptional()  );
        
        node = new ArtifactIncludeNode( newArtifact( "g:a:pom:v", null, true ) );
        assertEquals( "true", node.getDependency().getOptional()  );
        assertEquals( true, node.getDependency().isOptional()  );

        node = new ArtifactIncludeNode( newArtifact( "g:a:pom:v", null, false ) );
        assertEquals( "false", node.getDependency().getOptional()  );
        assertEquals( false, node.getDependency().isOptional()  );
    }

    private Artifact newArtifact( String coor, String scope )
        throws Exception
    {
        return newArtifact( coor, scope, null );
    }

    private Artifact newArtifact( String coor, String scope, Boolean optional )
        throws Exception
    {
        String[] gav = coor.split( ":" );
        String groupId = gav[0];
        String artifactId = gav[1];
        String version = null;
        String classifier = null;
        String type = null;

        if ( gav.length == 3 )
        {
            version = gav[2];
        }
        else if ( gav.length == 4 )
        {
            type = gav[2];
            version = gav[3];
        }        
        else if ( gav.length == 5 )
        {
            type = gav[2];
            classifier = gav[3];
            version = gav[4];
        }        
        
        if( optional != null )
        {
            VersionRange versionRange = VersionRange.createFromVersion( version );
            return artifactFactory.createArtifact( groupId, artifactId, versionRange, scope, type, classifier, optional );
        }
        else if ( gav.length == 3 )
        {
            return artifactFactory.createArtifact( groupId, artifactId, version, scope );
        }
        else if ( gav.length == 4 )
        {
            return artifactFactory.createArtifact( groupId, artifactId, version, scope, type, null );
        }
        else if ( gav.length == 5 )
        {
            return artifactFactory.createArtifact( groupId, artifactId, version, scope, type, classifier );
        }
        else
        {
            throw new IllegalArgumentException( "Can't translate coor to an Artifact" );
        }
    }
}
