/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed 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.
 */

package tests.api.java.lang.reflect;

import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;

/**
 * Tests generic reflection in more complicated cases. In particular: Scoping of
 * type parameters, equality of type parameters, wildcard types, parameterized
 * types and multiple bounds.
 */
@TestTargetClass(Method.class)
public class GenericReflectionCornerCases extends GenericReflectionTestsBase {

    static class Pair<T, S> {}

    static class WildcardEquality<T> {
        void wildcardEquality(Pair<? extends T, ? extends T> param) {}
    }
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.PARTIAL,
            notes = "Stress test.",
            method = "getTypeParameters",
            args = {}
        ),
        @TestTargetNew(
            level = TestLevel.PARTIAL,
            notes = "Stress test.",
            method = "getGenericParameterTypes",
            args = {}
        )
    })
    @SuppressWarnings("unchecked")
    public void testWildcardEquality() throws Exception {
        Class<? extends WildcardEquality> clazz = WildcardEquality.class;

        Method method = clazz.getDeclaredMethod("wildcardEquality", Pair.class);
        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
        assertLenghtOne(typeParameters);
        TypeVariable<?> typeParameter = typeParameters[0];

        Type[] parameterTypes = method.getGenericParameterTypes();
        assertLenghtOne(parameterTypes);
        Type parameter = parameterTypes[0];
        assertInstanceOf(ParameterizedType.class, parameter);
        ParameterizedType paramType = (ParameterizedType) parameter;
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
        assertEquals(2, actualTypeArguments.length);

        Type firstArgument = actualTypeArguments[0];
        assertInstanceOf(WildcardType.class, firstArgument);
        WildcardType firstWildcardArgument = (WildcardType) firstArgument;
        Type secondArgument = actualTypeArguments[1];
        assertInstanceOf(WildcardType.class, secondArgument);
        WildcardType secondWildcardArgument = (WildcardType) secondArgument;

        assertEquals(firstWildcardArgument, secondWildcardArgument);

        Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
        assertLenghtOne(firstWildcardArgumentUpperBounds);
        Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];

        Type[] secondWildcardArgumentUpperBounds = secondWildcardArgument.getUpperBounds();
        assertLenghtOne(secondWildcardArgumentUpperBounds);
        Type secondWildcardArgumentUpperBoundsType = secondWildcardArgumentUpperBounds[0];

        assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentUpperBoundsType);

        assertEquals(typeParameter, firstWildcardArgumentUpperBoundsType);
        assertEquals(typeParameter, secondWildcardArgumentUpperBoundsType);
    }

    static class WildcardUnEquality<T> {
        void wildcardUnEquality(Pair<? extends T, ? super T> param) {}
    }
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.PARTIAL,
            notes = "Stress test.",
            method = "getTypeParameters",
            args = {}
        ),
        @TestTargetNew(
            level = TestLevel.PARTIAL,
            notes = "Stress test.",
            method = "getGenericParameterTypes",
            args = {}
        )
    })
    @SuppressWarnings("unchecked")
    public void testWildcardUnEquality() throws Exception {
        Class<? extends WildcardUnEquality> clazz = WildcardUnEquality.class;

        Method method = clazz.getDeclaredMethod("wildcardUnEquality", Pair.class);
        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
        assertLenghtOne(typeParameters);
        TypeVariable<?> typeParameter = typeParameters[0];

        Type[] parameterTypes = method.getGenericParameterTypes();
        assertLenghtOne(parameterTypes);
        Type parameter = parameterTypes[0];
        assertInstanceOf(ParameterizedType.class, parameter);
        ParameterizedType paramType = (ParameterizedType) parameter;
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
        assertEquals(2, actualTypeArguments.length);

        Type firstArgument = actualTypeArguments[0];
        assertInstanceOf(WildcardType.class, firstArgument);
        WildcardType firstWildcardArgument = (WildcardType) firstArgument;
        Type secondArgument = actualTypeArguments[1];
        assertInstanceOf(WildcardType.class, secondArgument);
        WildcardType secondWildcardArgument = (WildcardType) secondArgument;

        assertNotEquals(firstWildcardArgument, secondWildcardArgument);

        Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
        assertLenghtOne(firstWildcardArgumentUpperBounds);
        Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];

        Type[] secondWildcardArgumentLowerBounds = secondWildcardArgument.getLowerBounds();
        assertLenghtOne(secondWildcardArgumentLowerBounds);
        Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentLowerBounds[0];

        assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
        assertEquals(typeParameter, firstWildcardArgumentUpperBoundsType);
        assertEquals(typeParameter, secondWildcardArgumentLoweroundsType);
    }

    static class MultipleBoundedWildcardUnEquality<T extends Object & Comparable<MultipleBoundedWildcardUnEquality<T>>> {
        void multipleBoundedWildcardUnEquality(Pair<? extends T, ? super T> param) {}
    }
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.PARTIAL,
            notes = "Stress test.",
            method = "getTypeParameters",
            args = {}
        ),
        @TestTargetNew(
            level = TestLevel.PARTIAL,
            notes = "Stress test.",
            method = "getGenericParameterTypes",
            args = {}
        )
    })
    @SuppressWarnings("unchecked")
    public void testMultipleBoundedWildcardUnEquality() throws Exception {
        Class<? extends MultipleBoundedWildcardUnEquality> clazz = MultipleBoundedWildcardUnEquality.class;

        // new WildcardEquality<Object>().wildcardEquality(new Pair<String,
        // Integer>());

        Method method = clazz.getDeclaredMethod("multipleBoundedWildcardUnEquality", Pair.class);
        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
        assertLenghtOne(typeParameters);
        TypeVariable<?> typeParameter = typeParameters[0];
        Type[] typeParameterBounds = typeParameter.getBounds();
        assertEquals(2, typeParameterBounds.length);
        assertEquals(Object.class, typeParameterBounds[0]);
        assertInstanceOf(ParameterizedType.class, typeParameterBounds[1]);
        ParameterizedType parameterizedType = (ParameterizedType) typeParameterBounds[1];
        assertEquals(Comparable.class, parameterizedType.getRawType());
        Type[] typeArguments = parameterizedType.getActualTypeArguments();
        assertLenghtOne(typeArguments);
        assertInstanceOf(ParameterizedType.class, typeArguments[0]);
        ParameterizedType type = (ParameterizedType) typeArguments[0];
        assertEquals(typeParameter, type.getActualTypeArguments()[0]);
        assertEquals(MultipleBoundedWildcardUnEquality.class, type.getRawType());

        Type[] parameterTypes = method.getGenericParameterTypes();
        assertLenghtOne(parameterTypes);
        Type parameter = parameterTypes[0];
        assertInstanceOf(ParameterizedType.class, parameter);
        ParameterizedType paramType = (ParameterizedType) parameter;
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
        assertEquals(2, actualTypeArguments.length);

        Type firstArgument = actualTypeArguments[0];
        assertInstanceOf(WildcardType.class, firstArgument);
        WildcardType firstWildcardArgument = (WildcardType) firstArgument;
        Type secondArgument = actualTypeArguments[1];
        assertInstanceOf(WildcardType.class, secondArgument);
        WildcardType secondWildcardArgument = (WildcardType) secondArgument;

        assertNotEquals(firstWildcardArgument, secondWildcardArgument);

        Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
        assertLenghtOne(firstWildcardArgumentUpperBounds);
        Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];

        Type[] secondWildcardArgumentLowerBounds = secondWildcardArgument.getLowerBounds();
        assertLenghtOne(secondWildcardArgumentLowerBounds);
        Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentLowerBounds[0];

        assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
    }

    static class MultipleBoundedWildcardEquality<T extends Object & Comparable<MultipleBoundedWildcardEquality<T>>> {
        void multipleBoundedWildcardEquality(Pair<? extends T, ? extends T> param) {}
    }
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.PARTIAL,
            notes = "Stress test.",
            method = "getTypeParameters",
            args = {}
        ),
        @TestTargetNew(
            level = TestLevel.PARTIAL,
            notes = "Stress test.",
            method = "getGenericParameterTypes",
            args = {}
        )
    })
    @SuppressWarnings("unchecked")
    public void testMultipleBoundedWildcard() throws Exception {
        Class<? extends MultipleBoundedWildcardEquality> clazz = MultipleBoundedWildcardEquality.class;

        Method method = clazz.getDeclaredMethod("multipleBoundedWildcardEquality", Pair.class);
        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
        assertLenghtOne(typeParameters);
        TypeVariable<?> typeParameter = typeParameters[0];
        Type[] typeParameterBounds = typeParameter.getBounds();
        assertEquals(2, typeParameterBounds.length);
        assertEquals(Object.class, typeParameterBounds[0]);
        assertInstanceOf(ParameterizedType.class, typeParameterBounds[1]);
        ParameterizedType parameterizedType = (ParameterizedType) typeParameterBounds[1];
        assertEquals(Comparable.class, parameterizedType.getRawType());
        Type[] typeArguments = parameterizedType.getActualTypeArguments();
        assertLenghtOne(typeArguments);
        assertInstanceOf(ParameterizedType.class, typeArguments[0]);
        ParameterizedType type = (ParameterizedType) typeArguments[0];
        assertEquals(typeParameter, type.getActualTypeArguments()[0]);
        assertEquals(MultipleBoundedWildcardEquality.class, type.getRawType());

        Type[] parameterTypes = method.getGenericParameterTypes();
        assertLenghtOne(parameterTypes);
        Type parameter = parameterTypes[0];
        assertInstanceOf(ParameterizedType.class, parameter);
        ParameterizedType paramType = (ParameterizedType) parameter;
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
        assertEquals(2, actualTypeArguments.length);

        Type firstArgument = actualTypeArguments[0];
        assertInstanceOf(WildcardType.class, firstArgument);
        WildcardType firstWildcardArgument = (WildcardType) firstArgument;
        Type secondArgument = actualTypeArguments[1];
        assertInstanceOf(WildcardType.class, secondArgument);
        WildcardType secondWildcardArgument = (WildcardType) secondArgument;

        assertEquals(firstWildcardArgument, secondWildcardArgument);

        Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
        assertLenghtOne(firstWildcardArgumentUpperBounds);
        Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];

        Type[] secondWildcardArgumentUpperBounds = secondWildcardArgument.getUpperBounds();
        assertLenghtOne(secondWildcardArgumentUpperBounds);
        Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentUpperBounds[0];

        assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
    }
}
