/*******************************************************************************
 * Copyright (c) 2010-present Sonatype, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Stuart McCulloch (Sonatype, Inc.) - initial API and implementation
 *******************************************************************************/
package org.eclipse.sisu.inject;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.AbstractMap;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;

import com.google.inject.ImplementedBy;
import com.google.inject.ProvidedBy;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.util.Types;

import junit.framework.TestCase;

public class TypeArgumentsTest
    extends TestCase
{
    static TypeLiteral<Object> OBJECT_TYPE = TypeLiteral.get( Object.class );

    static TypeLiteral<String> STRING_TYPE = TypeLiteral.get( String.class );

    static TypeLiteral<Float> FLOAT_TYPE = TypeLiteral.get( Float.class );

    static TypeLiteral<Short> SHORT_TYPE = TypeLiteral.get( Short.class );

    static TypeLiteral<Number> NUMBER_TYPE = TypeLiteral.get( Number.class );

    @SuppressWarnings( "rawtypes" )
    List rawList;

    List<Short> shortList;

    List<?> wildcardList;

    List<? extends String> wildcardStringList;

    @SuppressWarnings( "rawtypes" )
    Map rawMap;

    Map<String, Float> stringFloatMap;

    Map<?, ?> wildcardMap;

    Map<? extends Float, ? extends Short> wildcardFloatShortMap;

    interface CallableNumber<T extends Number>
        extends Callable<T>
    {
    }

    public void testTypeArguments()
    {
        TypeLiteral<?>[] types;

        assertEquals( OBJECT_TYPE, TypeArguments.get( getFieldType( "rawList" ), 0 ) );
        types = TypeArguments.get( getFieldType( "rawList" ) );
        assertEquals( 0, types.length );

        assertEquals( OBJECT_TYPE, TypeArguments.get( getFieldType( "rawMap" ), 0 ) );
        assertEquals( OBJECT_TYPE, TypeArguments.get( getFieldType( "rawMap" ), 1 ) );
        types = TypeArguments.get( getFieldType( "rawMap" ) );
        assertEquals( 0, types.length );

        assertEquals( SHORT_TYPE, TypeArguments.get( getFieldType( "shortList" ), 0 ) );
        types = TypeArguments.get( getFieldType( "shortList" ) );
        assertEquals( 1, types.length );
        assertEquals( SHORT_TYPE, types[0] );

        assertEquals( STRING_TYPE, TypeArguments.get( getFieldType( "stringFloatMap" ), 0 ) );
        assertEquals( FLOAT_TYPE, TypeArguments.get( getFieldType( "stringFloatMap" ), 1 ) );
        types = TypeArguments.get( getFieldType( "stringFloatMap" ) );
        assertEquals( 2, types.length );
        assertEquals( STRING_TYPE, types[0] );
        assertEquals( FLOAT_TYPE, types[1] );

        assertEquals( OBJECT_TYPE, TypeArguments.get( getFieldType( "wildcardList" ), 0 ) );
        types = TypeArguments.get( getFieldType( "wildcardList" ) );
        assertEquals( 1, types.length );
        assertEquals( OBJECT_TYPE, types[0] );

        assertEquals( OBJECT_TYPE, TypeArguments.get( getFieldType( "wildcardMap" ), 0 ) );
        assertEquals( OBJECT_TYPE, TypeArguments.get( getFieldType( "wildcardMap" ), 1 ) );
        types = TypeArguments.get( getFieldType( "wildcardMap" ) );
        assertEquals( 2, types.length );
        assertEquals( OBJECT_TYPE, types[0] );
        assertEquals( OBJECT_TYPE, types[1] );

        assertEquals( STRING_TYPE, TypeArguments.get( getFieldType( "wildcardStringList" ), 0 ) );
        types = TypeArguments.get( getFieldType( "wildcardStringList" ) );
        assertEquals( 1, types.length );
        assertEquals( STRING_TYPE, types[0] );

        assertEquals( FLOAT_TYPE, TypeArguments.get( getFieldType( "wildcardFloatShortMap" ), 0 ) );
        assertEquals( SHORT_TYPE, TypeArguments.get( getFieldType( "wildcardFloatShortMap" ), 1 ) );
        types = TypeArguments.get( getFieldType( "wildcardFloatShortMap" ) );
        assertEquals( 2, types.length );
        assertEquals( FLOAT_TYPE, types[0] );
        assertEquals( SHORT_TYPE, types[1] );

        final TypeLiteral<?> genericSuperType = TypeLiteral.get( CallableNumber.class ).getSupertype( Callable.class );

        assertEquals( NUMBER_TYPE, TypeArguments.get( genericSuperType, 0 ) );
        types = TypeArguments.get( genericSuperType );
        assertEquals( 1, types.length );
        assertEquals( NUMBER_TYPE, types[0] );
    }

    @SuppressWarnings( "rawtypes" )
    List[] rawListArray;

    List<Short>[] shortListArray;

    List<?>[] wildcardListArray;

    List<? extends String>[] wildcardStringListArray;

    @SuppressWarnings( "rawtypes" )
    Map[] rawMapArray;

    Map<String, Float>[] stringFloatMapArray;

    Map<?, ?>[] wildcardMapArray;

    Map<? extends Float, ? extends Short>[] wildcardFloatShortMapArray;

    List<String[]> stringArrayList;

    public void testComponentType()
    {
        TypeLiteral<?>[] types;

        types = TypeArguments.get( getFieldType( "rawListArray" ) );
        assertEquals( getFieldType( "rawList" ), types[0] );
        assertEquals( types[0], TypeArguments.get( getFieldType( "rawListArray" ), 0 ) );
        assertEquals( List.class, types[0].getType() );

        types = TypeArguments.get( getFieldType( "rawMapArray" ) );
        assertEquals( getFieldType( "rawMap" ), types[0] );
        assertEquals( types[0], TypeArguments.get( getFieldType( "rawMapArray" ), 0 ) );
        assertEquals( Map.class, types[0].getType() );

        types = TypeArguments.get( getFieldType( "shortListArray" ) );
        assertEquals( getFieldType( "shortList" ), types[0] );
        assertEquals( types[0], TypeArguments.get( getFieldType( "shortListArray" ), 0 ) );
        assertEquals( Types.listOf( Short.class ), types[0].getType() );

        types = TypeArguments.get( getFieldType( "stringFloatMapArray" ) );
        assertEquals( getFieldType( "stringFloatMap" ), types[0] );
        assertEquals( types[0], TypeArguments.get( getFieldType( "stringFloatMapArray" ), 0 ) );
        assertEquals( Types.mapOf( String.class, Float.class ), types[0].getType() );

        types = TypeArguments.get( getFieldType( "wildcardListArray" ) );
        assertEquals( getFieldType( "wildcardList" ), types[0] );
        assertEquals( types[0], TypeArguments.get( getFieldType( "wildcardListArray" ), 0 ) );
        assertEquals( Types.listOf( Types.subtypeOf( Object.class ) ), types[0].getType() );

        types = TypeArguments.get( getFieldType( "wildcardMapArray" ) );
        assertEquals( getFieldType( "wildcardMap" ), types[0] );
        assertEquals( types[0], TypeArguments.get( getFieldType( "wildcardMapArray" ), 0 ) );
        assertEquals( Types.mapOf( Types.subtypeOf( Object.class ), Types.subtypeOf( Object.class ) ),
                      types[0].getType() );

        types = TypeArguments.get( getFieldType( "wildcardStringListArray" ) );
        assertEquals( getFieldType( "wildcardStringList" ), types[0] );
        assertEquals( types[0], TypeArguments.get( getFieldType( "wildcardStringListArray" ), 0 ) );
        assertEquals( Types.listOf( Types.subtypeOf( String.class ) ), types[0].getType() );

        types = TypeArguments.get( getFieldType( "wildcardFloatShortMapArray" ) );
        assertEquals( getFieldType( "wildcardFloatShortMap" ), types[0] );
        assertEquals( types[0], TypeArguments.get( getFieldType( "wildcardFloatShortMapArray" ), 0 ) );
        assertEquals( Types.mapOf( Types.subtypeOf( Float.class ), Types.subtypeOf( Short.class ) ),
                      types[0].getType() );

        types = TypeArguments.get( TypeArguments.get( getFieldType( "stringArrayList" ) )[0] );
        assertEquals( STRING_TYPE, types[0] );
        assertEquals( types[0], TypeArguments.get( TypeArguments.get( getFieldType( "stringArrayList" ), 0 ), 0 ) );
    }

    public void testTypeArgumentRangeChecks()
    {
        try
        {
            TypeArguments.get( getFieldType( "stringFloatMap" ), -1 );
            fail( "Expected IndexOutOfBoundsException" );
        }
        catch ( final IndexOutOfBoundsException e )
        {
        }
        try
        {
            TypeArguments.get( getFieldType( "stringFloatMap" ), 2 );
            fail( "Expected IndexOutOfBoundsException" );
        }
        catch ( final IndexOutOfBoundsException e )
        {
        }

        try
        {
            TypeArguments.get( getFieldType( "wildcardStringListArray" ), -1 );
            fail( "Expected IndexOutOfBoundsException" );
        }
        catch ( final IndexOutOfBoundsException e )
        {
        }
        try
        {
            TypeArguments.get( getFieldType( "wildcardStringListArray" ), 1 );
            fail( "Expected IndexOutOfBoundsException" );
        }
        catch ( final IndexOutOfBoundsException e )
        {
        }
    }

    static class CallableImpl<T>
        implements Callable<T>
    {
        public T call()
            throws Exception
        {
            return null;
        }
    }

    static class CallableNumberImpl<T extends Number>
        implements CallableNumber<T>
    {
        public T call()
            throws Exception
        {
            return null;
        }
    }

    @SuppressWarnings( "rawtypes" )
    static class CallableListImpl
        implements Callable<List>
    {
        public List call()
            throws Exception
        {
            return null;
        }
    }

    @SuppressWarnings( "rawtypes" )
    public void testIsAssignableFrom()
    {
        // === simple types ===

        assertTrue( TypeArguments.isAssignableFrom( TypeLiteral.get( Object.class ),
                                                    TypeLiteral.get( String.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( TypeLiteral.get( Number.class ), TypeLiteral.get( Short.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( TypeLiteral.get( Collection.class ),
                                                    TypeLiteral.get( Set.class ) ) );

        // === generic types ===

        assertFalse( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<Collection>>()
        {
        }, TypeLiteral.get( CallableListImpl.class ) ) ); // not assignable since no wild-card
        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<List>>()
        {
        }, TypeLiteral.get( CallableListImpl.class ) ) );
        assertFalse( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<String>>()
        {
        }, TypeLiteral.get( CallableListImpl.class ) ) );

        // === unbound type-variables ===

        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<Callable>()
        {
        }, TypeLiteral.get( Callable.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<Callable>()
        {
        }, TypeLiteral.get( CallableImpl.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<String>>()
        {
        }, TypeLiteral.get( CallableImpl.class ) ) );
        assertFalse( TypeArguments.isAssignableFrom( new TypeLiteral<CallableImpl>()
        {
        }, TypeLiteral.get( Callable.class ) ) );

        // === bound type-variables ===

        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<CallableNumber>()
        {
        }, TypeLiteral.get( CallableNumberImpl.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<CallableNumber<Number>>()
        {
        }, TypeLiteral.get( CallableNumberImpl.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<CallableNumber<Float>>()
        {
        }, TypeLiteral.get( CallableNumberImpl.class ) ) );
        assertFalse( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<String>>()
        {
        }, TypeLiteral.get( CallableNumberImpl.class ) ) ); // mismatched type-bounds

        // === unbound wild-cards ===

        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<?>>()
        {
        }, TypeLiteral.get( CallableImpl.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<?>>()
        {
        }, TypeLiteral.get( CallableNumberImpl.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<CallableNumber<?>>()
        {
        }, TypeLiteral.get( CallableNumberImpl.class ) ) );

        // === bound wild-cards ===

        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<? extends Collection>>()
        {
        }, TypeLiteral.get( CallableListImpl.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<? extends Number>>()
        {
        }, TypeLiteral.get( CallableNumberImpl.class ) ) );
        assertTrue( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<? extends Float>>()
        {
        }, TypeLiteral.get( CallableNumberImpl.class ) ) );
        assertFalse( TypeArguments.isAssignableFrom( new TypeLiteral<Callable<? extends String>>()
        {
        }, TypeLiteral.get( CallableNumberImpl.class ) ) );

        // === array types ===

        assertTrue( TypeArguments.isAssignableFrom( TypeLiteral.get( Types.arrayOf( Object.class ) ),
                                                    TypeLiteral.get( Types.arrayOf( String.class ) ) ) );
        assertTrue( TypeArguments.isAssignableFrom( TypeLiteral.get( Types.arrayOf( Number.class ) ),
                                                    TypeLiteral.get( Types.arrayOf( Float.class ) ) ) );

        // === mismatched types ===

        assertFalse( TypeArguments.isAssignableFrom( TypeLiteral.get( Types.arrayOf( Object.class ) ),
                                                     TypeLiteral.get( Types.listOf( Object.class ) ) ) );
        assertFalse( TypeArguments.isAssignableFrom( TypeLiteral.get( Types.listOf( Object.class ) ),
                                                     TypeLiteral.get( Types.arrayOf( Object.class ) ) ) );

        // === corner case ===

        final Type T = (Type) Proxy.newProxyInstance( getClass().getClassLoader(),
                                                      new Class<?>[] { TypeVariable.class }, new InvocationHandler()
                                                      {
                                                          public Object invoke( final Object proxy, final Method method,
                                                                                final Object[] args )
                                                              throws Throwable
                                                          {
                                                              final String name = method.getName();
                                                              if ( "getBounds".equals( name ) )
                                                              {
                                                                  return new Type[] { String.class };
                                                              }
                                                              if ( "getName".equals( name ) )
                                                              {
                                                                  return "T";
                                                              }
                                                              if ( "hashCode".equals( name ) )
                                                              {
                                                                  return hashCode();
                                                              }
                                                              if ( "equals".equals( name ) )
                                                              {
                                                                  return equals( args[0] );
                                                              }
                                                              return null;
                                                          }
                                                      } );

        final Type callableT =
            (Type) Proxy.newProxyInstance( getClass().getClassLoader(), new Class<?>[] { ParameterizedType.class },
                                           new InvocationHandler()
                                           {
                                               public Object invoke( final Object proxy, final Method method,
                                                                     final Object[] args )
                                                   throws Throwable
                                               {
                                                   final String name = method.getName();
                                                   if ( "getActualTypeArguments".equals( name ) )
                                                   {
                                                       return new Type[] { T };
                                                   }
                                                   if ( "getRawType".equals( name ) )
                                                   {
                                                       return Callable.class;
                                                   }
                                                   if ( "hashCode".equals( name ) )
                                                   {
                                                       return hashCode();
                                                   }
                                                   if ( "equals".equals( name ) )
                                                   {
                                                       return equals( args[0] );
                                                   }
                                                   return null;
                                               }
                                           } );

        assertFalse( TypeArguments.isAssignableFrom( TypeLiteral.get( callableT ),
                                                     TypeLiteral.get( Callable.class ) ) );

        assertFalse( TypeArguments.isAssignableFrom( TypeLiteral.get( callableT ),
                                                     TypeLiteral.get( CallableNumberImpl.class ) ) );
    }

    public void testIsConcrete()
    {
        assertFalse( TypeArguments.isConcrete( Map.class ) );
        assertFalse( TypeArguments.isConcrete( AbstractMap.class ) );
        assertTrue( TypeArguments.isConcrete( HashMap.class ) );

        assertFalse( TypeArguments.isConcrete( new TypeLiteral<Map<String, String>>()
        {
        } ) );
        assertFalse( TypeArguments.isConcrete( new TypeLiteral<AbstractMap<String, String>>()
        {
        } ) );
        assertTrue( TypeArguments.isConcrete( new TypeLiteral<HashMap<String, String>>()
        {
        } ) );
    }

    @ImplementedBy( Object.class )
    static interface Implicit1<T>
    {
    }

    static class SomeProvider
        implements Provider<Object>
    {
        public Object get()
        {
            return null;
        }
    }

    @ProvidedBy( SomeProvider.class )
    static interface Implicit2<T>
    {
    }

    public void testIsImplicit()
    {
        assertFalse( TypeArguments.isImplicit( Map.class ) );
        assertFalse( TypeArguments.isImplicit( AbstractMap.class ) );
        assertTrue( TypeArguments.isImplicit( HashMap.class ) );

        assertFalse( TypeArguments.isImplicit( new TypeLiteral<Map<String, String>>()
        {
        } ) );
        assertFalse( TypeArguments.isImplicit( new TypeLiteral<AbstractMap<String, String>>()
        {
        } ) );
        assertTrue( TypeArguments.isImplicit( new TypeLiteral<HashMap<String, String>>()
        {
        } ) );

        assertTrue( TypeArguments.isImplicit( Implicit1.class ) );
        assertTrue( TypeArguments.isImplicit( Implicit2.class ) );

        assertTrue( TypeArguments.isImplicit( new TypeLiteral<Implicit1<String>>()
        {
        } ) );
        assertTrue( TypeArguments.isImplicit( new TypeLiteral<Implicit2<String>>()
        {
        } ) );
    }

    private static TypeLiteral<?> getFieldType( final String name )
    {
        try
        {
            return TypeLiteral.get( TypeArgumentsTest.class.getDeclaredField( name ).getGenericType() );
        }
        catch ( final NoSuchFieldException e )
        {
            throw new IllegalArgumentException( "Unknown test field " + name );
        }
    }
}
