package org.apache.maven.shared.dependency.analyzer.asm;

/*
 * 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.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.*;
import org.objectweb.asm.signature.SignatureVisitor;

import static org.junit.Assert.assertEquals;

/**
 * Tests <code>DependencyVisitor</code>.
 * 
 * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
 */
public class DependencyVisitorTest
{
    private final ResultCollector resultCollector = new ResultCollector();
    private DefaultClassVisitor visitor;
    private MethodVisitor mv;

    @Before
    public void setUp()
    {
        AnnotationVisitor annotationVisitor = new DefaultAnnotationVisitor( resultCollector );
        SignatureVisitor signatureVisitor = new DefaultSignatureVisitor( resultCollector );
        FieldVisitor fieldVisitor = new DefaultFieldVisitor( annotationVisitor, resultCollector );
        mv = new DefaultMethodVisitor( annotationVisitor, signatureVisitor, resultCollector);
        visitor = new DefaultClassVisitor( signatureVisitor, annotationVisitor, fieldVisitor, mv, resultCollector);
    }

    @Test
    public void testVisitWithDefaultSuperclass()
    {
        // class a.b.c
        visitor.visit( 50, 0, "a/b/c", null, "java/lang/Object", null );

        assertClasses( "java.lang.Object" );
    }

    @Test
    public void testVisitWithSuperclass()
    {
        // class a.b.c
        visitor.visit( 50, 0, "a/b/c", null, "x/y/z", null );

        assertClasses( "x.y.z" );
    }

    @Test
    public void testVisitWithInterface()
    {
        // class a.b.c implements x.y.z
        visitor.visit( 50, 0, "a/b/c", null, "java/lang/Object", new String[] { "x/y/z" } );

        assertClasses( "java.lang.Object", "x.y.z" );
    }

    @Test
    public void testVisitWithInterfaces()
    {
        // class a.b.c implements p.q.r, x.y.z
        visitor.visit( 50, 0, "a/b/c", null, "java/lang/Object", new String[] { "p/q/r", "x/y/z" } );

        assertClasses( "java.lang.Object", "p.q.r", "x.y.z" );
    }

    @Test
    public void testVisitWithUnboundedClassTypeParameter()
    {
        // class a.b.c<T>
        String signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;";

        visitor.visit( 50, 0, "a/b/c", signature, "java/lang/Object", null );

        assertClasses( "java.lang.Object" );
    }

    @Test
    public void testVisitWithBoundedClassTypeParameter()
    {
        // class a.b.c<T extends x.y.z>
        String signature = "<T:Lx/y/z;>Ljava/lang/Object;";

        visitor.visit( 50, 0, "a/b/c", signature, "java/lang/Object", null );

        assertClasses( "java.lang.Object", "x.y.z" );
    }

    @Test
    public void testVisitWithBoundedClassTypeParameters()
    {
        // class a.b.c<K extends p.q.r, V extends x.y.z>
        String signature = "<K:Lp/q/r;V:Lx/y/z;>Ljava/lang/Object;";

        visitor.visit( 50, 0, "a/b/c", signature, "java/lang/Object", null );

        assertClasses( "java.lang.Object", "p.q.r", "x.y.z" );
    }

    @Test
    public void testVisitWithGenericInterface()
    {
        // class a.b.c implements p.q.r<x.y.z>
        String signature = "Ljava/lang/Object;Lp/q/r<Lx/y/z;>;";

        visitor.visit( 50, 0, "a/b/c", signature, "java/lang/Object", new String[] { "p.q.r" } );

        assertClasses( "java.lang.Object", "p.q.r", "x.y.z" );
    }

    @Test
    public void testVisitWithInterfaceBound()
    {
        // class a.b.c<T> implements x.y.z<T>
        String signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;Lx/y/z<TT;>;";

        visitor.visit( 50, 0, "a/b/c", signature, "java/lang/Object", new String[] { "x.y.z" } );

        assertClasses( "java.lang.Object", "x.y.z" );
    }

    // visitSource tests ------------------------------------------------------

    @Test
    public void testVisitSource()
    {
        visitor.visitSource( null, null );

        assertNoClasses();
    }

    // visitOuterClass tests --------------------------------------------------

    @Test
    public void testVisitOuterClass()
    {
        // class a.b.c
        // {
        //     class ...
        //     {
        //     }
        // }
        visitor.visitOuterClass( "a/b/c", null, null );

        assertNoClasses();
    }

    @Test
    public void testVisitOuterClassInMethod()
    {
        // class a.b.c
        // {
        //     x.y.z x(p.q.r p)
        //     {
        //         class ...
        //         {
        //         }
        //     }
        // }
        visitor.visitOuterClass( "a/b/c", "x", "(Lp/q/r;)Lx/y/z;" );

        assertNoClasses();
    }

    // visitAnnotation tests --------------------------------------------------

    @Test
    public void testVisitAnnotation()
    {
        assertVisitor( visitor.visitAnnotation( "La/b/c;", false ) );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitAnnotationWithRuntimeVisibility()
    {
        assertVisitor( visitor.visitAnnotation( "La/b/c;", true ) );

        assertClasses( "a.b.c" );
    }

    // visitAttribute tests ---------------------------------------------------

    @Test
    public void testVisitAttribute()
    {
        visitor.visitAttribute( new MockAttribute( "a" ) );

        assertNoClasses();
    }

    // visitInnerClass tests --------------------------------------------------

    @Test
    public void testVisitInnerClass()
    {
        // TODO: ensure innerName is correct

        // class a.b.c { class x.y.z { } }
        visitor.visitInnerClass( "x/y/z", "a/b/c", "z", 0 );

        assertNoClasses();
    }

    @Test
    public void testVisitInnerClassAnonymous()
    {
        // class a.b.c { new class x.y.z { } }
        visitor.visitInnerClass( "x/y/z$1", "a/b/c", null, 0 );

        assertNoClasses();
    }

    // visitField tests -------------------------------------------------------

    @Test
    public void testVisitField()
    {
        // a.b.c a
        assertVisitor( visitor.visitField( 0, "a", "La/b/c;", null, null ) );

        assertClasses( "a.b.c" );
    }

    // TODO: determine actual use of default values
    // public void testVisitFieldWithValue()
    // {
    // }

    @Test
    public void testVisitFieldArray()
    {
        // a.b.c[] a
        assertVisitor( visitor.visitField( 0, "a", "[La/b/c;", null, null ) );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitFieldGeneric()
    {
        // a.b.c<x.y.z> a
        assertVisitor( visitor.visitField( 0, "a", "La/b/c;", "La/b/c<Lx/y/z;>;", null ) );

        assertClasses( "a.b.c", "x.y.z" );
    }

    // visitMethod tests ------------------------------------------------------

    @Test
    public void testVisitMethod()
    {
        // void a()
        assertVisitor( visitor.visitMethod( 0, "a", "()V", null, null ) );

        assertNoClasses();
    }

    @Test
    public void testVisitMethodWithPrimitiveArgument()
    {
        // void a(int)
        assertVisitor( visitor.visitMethod( 0, "a", "(I)V", null, null ) );

        assertNoClasses();
    }

    @Test
    public void testVisitMethodWithPrimitiveArrayArgument()
    {
        // void a(int[])
        assertVisitor( visitor.visitMethod( 0, "a", "([I)V", null, null ) );

        assertNoClasses();
    }

    @Test
    public void testVisitMethodWithObjectArgument()
    {
        // void a(a.b.c)
        assertVisitor( visitor.visitMethod( 0, "a", "(La/b/c;)V", null, null ) );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodWithObjectArguments()
    {
        // void a(a.b.c, x.y.z)
        assertVisitor( visitor.visitMethod( 0, "a", "(La/b/c;Lx/y/z;)V", null, null ) );

        assertClasses( "a.b.c", "x.y.z" );
    }

    @Test
    public void testVisitMethodWithObjectArrayArgument()
    {
        // void a(a.b.c[])
        assertVisitor( visitor.visitMethod( 0, "a", "([La/b/c;)V", null, null ) );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodWithGenericArgument()
    {
        // void a(a.b.c<x.y.z>)
        assertVisitor( visitor.visitMethod( 0, "a", "(La/b/c;)V", "(La/b/c<Lx/y/z;>;)V", null ) );

        assertClasses( "a.b.c", "x.y.z" );
    }

    @Test
    public void testVisitMethodWithPrimitiveReturnType()
    {
        // int a()
        assertVisitor( visitor.visitMethod( 0, "a", "()I", null, null ) );

        assertNoClasses();
    }

    @Test
    public void testVisitMethodWithPrimitiveArrayReturnType()
    {
        // int[] a()
        assertVisitor( visitor.visitMethod( 0, "a", "()[I", null, null ) );

        assertNoClasses();
    }

    @Test
    public void testVisitMethodWithObjectReturnType()
    {
        // a.b.c a()
        assertVisitor( visitor.visitMethod( 0, "a", "()La/b/c;", null, null ) );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodWithObjectArrayReturnType()
    {
        // a.b.c[] a()
        assertVisitor( visitor.visitMethod( 0, "a", "()[La/b/c;", null, null ) );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodWithException()
    {
        // void a() throws a.b.c
        assertVisitor( visitor.visitMethod( 0, "a", "()V", null, new String[] { "a/b/c" } ) );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodWithExceptions()
    {
        // void a() throws a.b.c, x.y.z
        assertVisitor( visitor.visitMethod( 0, "a", "()V", null, new String[] { "a/b/c", "x/y/z" } ) );

        assertClasses( "a.b.c", "x.y.z" );
    }

    // visitAnnotationDefault tests -------------------------------------------

    @Test
    public void testVisitAnnotationDefault()
    {
        assertVisitor( mv.visitAnnotationDefault() );
        assertNoClasses();
    }

    // visitParameterAnnotation tests -------------------------------------------

    @Test
    public void testVisitParameterAnnotation()
    {
        // @a.b.c
        assertVisitor( mv.visitParameterAnnotation( 0, "La/b/c;", false ) );

        assertClasses( "a.b.c" );
    }

    // visitCode tests --------------------------------------------------------

    @Test
    public void testVisitCode()
    {
        mv.visitCode();

        assertNoClasses();
    }

    // visitFrame tests -------------------------------------------------------

    @Test
    public void testVisitFrame()
    {
        mv.visitFrame( Opcodes.F_NEW, 0, new Object[0], 0, new Object[0] );

        assertNoClasses();
    }

    // visitInsn tests --------------------------------------------------------

    @Test
    public void testVisitInsn()
    {
        mv.visitInsn( Opcodes.NOP );

        assertNoClasses();
    }

    // visitIntInsn tests -----------------------------------------------------

    @Test
    public void testVisitIntInsn()
    {
        mv.visitIntInsn( Opcodes.BIPUSH, 0 );

        assertNoClasses();
    }

    // visitVarInsn tests -----------------------------------------------------

    @Test
    public void testVisitVarInsn()
    {
        mv.visitVarInsn( Opcodes.ILOAD, 0 );

        assertNoClasses();
    }

    // visitTypeInsn tests ----------------------------------------------------

    @Test
    public void testVisitTypeInsn()
    {
        mv.visitTypeInsn( Opcodes.NEW, "a/b/c" );

        assertClasses( "a.b.c" );
    }

    // visitFieldInsn tests ---------------------------------------------------

    @Test
    public void testVisitFieldInsnWithPrimitive()
    {
        mv.visitFieldInsn( Opcodes.GETFIELD, "a/b/c", "x", "I" );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitFieldInsnWithObject()
    {
        mv.visitFieldInsn( Opcodes.GETFIELD, "a/b/c", "x", "Lx/y/z;" );

        assertClasses( "a.b.c" );
    }

    // visitMethodInsn tests --------------------------------------------------

    @Test
    public void testVisitMethodInsn()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()V", false );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodInsnWithPrimitiveArgument()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "(I)V", false );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodInsnWithPrimitiveArrayArgument()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "([I)V", false );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodInsnWithObjectArgument()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "(Lx/y/z;)V", false );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodInsnWithObjectArguments()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "(Lp/q/r;Lx/y/z;)V", false );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodInsnWithObjectArrayArgument()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "([Lx/y/z;)V", false );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodInsnWithPrimitiveReturnType()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()I", false );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodInsnWithPrimitiveArrayReturnType()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()[I", false );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodInsnWithObjectReturnType()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()Lx/y/z;", false );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitMethodInsnWithObjectArrayReturnType()
    {
        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()[Lx/y/z;", false );

        assertClasses( "a.b.c" );
    }

    // visitJumpInsn tests ----------------------------------------------------

    @Test
    public void testVisitJumpInsn()
    {
        mv.visitJumpInsn( Opcodes.IFEQ, new Label() );

        assertNoClasses();
    }

    // visitLabel tests -------------------------------------------------------

    @Test
    public void testVisitLabel()
    {
        mv.visitLabel( new Label() );

        assertNoClasses();
    }

    // visitLdcInsn tests -----------------------------------------------------

    @Test
    public void testVisitLdcInsnWithNonType()
    {
        mv.visitLdcInsn( "a" );

        assertNoClasses();
    }

    @Test
    public void testVisitLdcInsnWithPrimitiveType()
    {
        mv.visitLdcInsn( Type.INT_TYPE );

        assertNoClasses();
    }

    @Test
    public void testVisitLdcInsnWithObjectType()
    {
        mv.visitLdcInsn( Type.getType( "La/b/c;" ) );

        assertClasses( "a.b.c" );
    }

    // visitIincInsn tests ----------------------------------------------------

    @Test
    public void testVisitIincInsn()
    {
        mv.visitIincInsn( 0, 1 );

        assertNoClasses();
    }

    // visitTableSwitchInsn tests ---------------------------------------------

    @Test
    public void testVisitTableSwitchInsn()
    {
        mv.visitTableSwitchInsn( 0, 1, new Label(), new Label() );

        assertNoClasses();
    }

    // visitLookupSwitchInsn tests --------------------------------------------

    @Test
    public void testVisitLookupSwitchInsn()
    {
        mv.visitLookupSwitchInsn( new Label(), new int[] { 0 }, new Label[] { new Label() } );

        assertNoClasses();
    }

    // visitMultiANewArrayInsn tests ------------------------------------------

    @Test
    public void testVisitMultiANewArrayInsnWithPrimitive()
    {
        mv.visitMultiANewArrayInsn( "I", 2 );

        assertNoClasses();
    }

    @Test
    public void testVisitMultiANewArrayInsnWithObject()
    {
        mv.visitMultiANewArrayInsn( "La/b/c;", 2 );

        assertClasses( "a.b.c" );
    }

    // visitTryCatchBlock tests -----------------------------------------------

    @Test
    public void testVisitTryCatchBlock()
    {
        mv.visitTryCatchBlock( new Label(), new Label(), new Label(), "a/b/c" );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitTryCatchBlockForFinally()
    {
        mv.visitTryCatchBlock( new Label(), new Label(), new Label(), null );

        assertNoClasses();
    }

    // visitLocalVariable tests -----------------------------------------------

    @Test
    public void testVisitLocalVariableWithPrimitive()
    {
        mv.visitLocalVariable( "a", "I", null, new Label(), new Label(), 0 );

        assertNoClasses();
    }

    @Test
    public void testVisitLocalVariableWithPrimitiveArray()
    {
        mv.visitLocalVariable( "a", "[I", null, new Label(), new Label(), 0 );

        assertNoClasses();
    }

    @Test
    public void testVisitLocalVariableWithObject()
    {
        mv.visitLocalVariable( "a", "La/b/c;", null, new Label(), new Label(), 0 );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitLocalVariableWithObjectArray()
    {
        mv.visitLocalVariable( "a", "[La/b/c;", null, new Label(), new Label(), 0 );

        assertClasses( "a.b.c" );
    }

    @Test
    public void testVisitLocalVariableWithGenericObject()
    {
        mv.visitLocalVariable( "a", "La/b/c;", "La/b/c<Lx/y/z;>;", new Label(), new Label(), 0 );

        assertClasses( "a.b.c", "x.y.z" );
    }

    @Test
    public void testVisitLocalVariableWithGenericObjectArray()
    {
        mv.visitLocalVariable( "a", "La/b/c;", "[La/b/c<Lx/y/z;>;", new Label(), new Label(), 0 );

        assertClasses( "a.b.c", "x.y.z" );
    }

    // visitLineNumber tests --------------------------------------------------

    @Test
    public void testVisitLineNumber()
    {
        mv.visitLineNumber( 0, new Label() );

        assertNoClasses();
    }

    // visitMaxs tests --------------------------------------------------------

    @Test
    public void testVisitMaxs()
    {
        mv.visitMaxs( 0, 0 );

        assertNoClasses();
    }

    private void assertVisitor( Object actualVisitor )
    {
        //assertEquals( visitor, actualVisitor );
    }

    private void assertNoClasses()
    {
        assertClasses( Collections.emptySet() );
    }

    private void assertClasses( String element )
    {
        assertClasses( Collections.singleton( element ) );
    }

    private void assertClasses( String expectedClass1, String expectedClass2 )
    {
        assertClasses( new String[] { expectedClass1, expectedClass2 } );
    }

    private void assertClasses( String expectedClass1, String expectedClass2, String expectedClass3 )
    {
        assertClasses( new String[] { expectedClass1, expectedClass2, expectedClass3 } );
    }

    private void assertClasses( String[] expectedClasses )
    {
        assertClasses( new HashSet<>( Arrays.asList( expectedClasses ) ) );
    }

    private void assertClasses( Set<String> expectedClasses )
    {
        assertEquals( expectedClasses, resultCollector.getDependencies() );
    }
}
