import otherpackage.OtherPackageClass;

import java.io.Serializable;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ClassAttrs {
    ClassAttrs() {
        /* local, not anonymous, not member */
        class ConsInnerNamed {
            public void showMe() {
                printClassAttrs(this.getClass());
            }
        }

        ConsInnerNamed cinner = new ConsInnerNamed();
        cinner.showMe();
    }

    public class PublicInnerClass {
    }

    protected class ProtectedInnerClass {
    }

    private class PrivateInnerClass {
    }

    class PackagePrivateInnerClass {
    }

    public interface PublicInnerInterface {
    }

    protected interface ProtectedInnerInterface {
    }

    private interface PrivateInnerInterface {
    }

    interface PackagePrivateInnerInterface {
    }

    private static void showModifiers(Class<?> c) {
        System.out.println(Modifier.toString(c.getModifiers()) + " " + c.getName());
    }

    // https://code.google.com/p/android/issues/detail?id=56267
    private static void test56267() {
        // Primitive classes.
        showModifiers(int.class);
        showModifiers(int[].class);

        // Regular classes.
        showModifiers(Object.class);
        showModifiers(Object[].class);

        // Inner classes.
        showModifiers(PublicInnerClass.class);
        showModifiers(PublicInnerClass[].class);
        showModifiers(ProtectedInnerClass.class);
        showModifiers(ProtectedInnerClass[].class);
        showModifiers(PrivateInnerClass.class);
        showModifiers(PrivateInnerClass[].class);
        showModifiers(PackagePrivateInnerClass.class);
        showModifiers(PackagePrivateInnerClass[].class);

        // Regular interfaces.
        showModifiers(Serializable.class);
        showModifiers(Serializable[].class);

        // Inner interfaces.
        showModifiers(PublicInnerInterface.class);
        showModifiers(PublicInnerInterface[].class);
        showModifiers(ProtectedInnerInterface.class);
        showModifiers(ProtectedInnerInterface[].class);
        showModifiers(PrivateInnerInterface.class);
        showModifiers(PrivateInnerInterface[].class);
        showModifiers(PackagePrivateInnerInterface.class);
        showModifiers(PackagePrivateInnerInterface[].class);
    }

    public static void main() {
        test56267();

        printClassAttrs(ClassAttrs.class);
        printClassAttrs(OtherClass.class);
        printClassAttrs(OtherPackageClass.class);

        /* local, not anonymous, not member */
        class InnerNamed {
            public void showMe() {
                printClassAttrs(this.getClass());
            }
        }
        InnerNamed inner = new InnerNamed();
        inner.showMe();

        ClassAttrs attrs = new ClassAttrs();
        try {
            /* anonymous, not local, not member */
            printClassAttrs(Class.forName("ClassAttrs$1")); // ClassAttrs$1.j
        } catch (ClassNotFoundException e) {
            System.out.println("FAILED: " + e);
            e.printStackTrace(System.out);
            throw new AssertionError(e);
        }

        /* member, not anonymous, not local */
        printClassAttrs(MemberClass.class);

        /* fancy */
        printClassAttrs(FancyClass.class);

        try {
            Constructor<?> cons;
            cons = MemberClass.class.getConstructor(MemberClass.class);
            System.out.println("constructor signature: "
                    + getSignatureAttribute(cons));

            Method meth;
            meth = MemberClass.class.getMethod("foo");
            System.out.println("method signature: "
                    + getSignatureAttribute(meth));

            Field field;
            field = MemberClass.class.getField("mWha");
            System.out.println("field signature: "
                    + getSignatureAttribute(field));
        } catch (NoSuchMethodException nsme) {
            System.out.println("FAILED: " + nsme);
        } catch (NoSuchFieldException nsfe) {
            System.out.println("FAILED: " + nsfe);
        } catch (RuntimeException re) {
            System.out.println("FAILED: " + re);
            re.printStackTrace(System.out);
        }

        test_isAssignableFrom();
        test_isInstance();
    }

    private static void test_isAssignableFrom() {
        // Can always assign to things of the same type.
        assertTrue(String.class.isAssignableFrom(String.class));

        // Can assign any reference to java.lang.Object.
        assertTrue(Object.class.isAssignableFrom(Object.class));
        assertTrue(Object.class.isAssignableFrom(Class.class));
        assertTrue(Object.class.isAssignableFrom(String.class));
        assertFalse(Object.class.isAssignableFrom(int.class));
        assertFalse(Object.class.isAssignableFrom(long.class));

        // Interfaces.
        assertTrue(CharSequence.class.isAssignableFrom(String.class));
        assertFalse(CharSequence.class.isAssignableFrom(Object.class));

        // Superclasses.
        assertTrue(AccessibleObject.class.isAssignableFrom(Method.class));
        assertFalse(Method.class.isAssignableFrom(AccessibleObject.class));

        // Arrays.
        assertTrue(int[].class.isAssignableFrom(int[].class));
        assertFalse(int[].class.isAssignableFrom(char[].class));
        assertFalse(char[].class.isAssignableFrom(int[].class));
        assertTrue(Object.class.isAssignableFrom(int[].class));
        assertFalse(int[].class.isAssignableFrom(Object.class));

        try {
            assertFalse(Object.class.isAssignableFrom(null));
            fail();
        } catch (NullPointerException expected) {
        }
    }

    private static void test_isInstance() {
        // Can always assign to things of the same type.
        assertTrue(String.class.isInstance("hello"));

        // Can assign any reference to java.lang.Object.
        assertTrue(Object.class.isInstance(new Object()));
        assertTrue(Object.class.isInstance(Class.class));
        assertTrue(Object.class.isInstance("hello"));

        // Interfaces.
        assertTrue(CharSequence.class.isInstance("hello"));
        assertFalse(CharSequence.class.isInstance(new Object()));

        // Superclasses.
        assertTrue(AccessibleObject.class.isInstance(Method.class.getDeclaredMethods()[0]));
        assertFalse(Method.class.isInstance(Method.class.getDeclaredFields()[0]));

        // Arrays.
        assertTrue(int[].class.isInstance(new int[0]));
        assertFalse(int[].class.isInstance(new char[0]));
        assertFalse(char[].class.isInstance(new int[0]));
        assertTrue(Object.class.isInstance(new int[0]));
        assertFalse(int[].class.isInstance(new Object()));

        assertFalse(Object.class.isInstance(null));
    }

    private static void assertTrue(boolean b) {
        if (!b) throw new RuntimeException();
    }

    private static void assertFalse(boolean b) {
        if (b) throw new RuntimeException();
    }

    private static void fail() {
        throw new RuntimeException();
    }

    /* to call the (out-of-scope) <code>getSignatureAttribute</code> methods */
    public static String getSignatureAttribute(Object obj) {
        Method method;
        try {
            Class<?> c = obj.getClass();
            if (c == Method.class || c == Constructor.class) {
              c = Executable.class;
            }
            method = c.getDeclaredMethod("getSignatureAttribute");
            method.setAccessible(true);
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
            return "<unknown>";
        }

        try {
            return (String) method.invoke(obj);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            throw new RuntimeException(ex);
        }
    }

    /* for reflection testing */
    static class MemberClass<XYZ> {
        public MemberClass<XYZ> mWha;

        public MemberClass(MemberClass<XYZ> memb) {
            mWha = memb;
        }

        public Class<XYZ> foo() throws NoSuchMethodException {
            return null;
        }
    }

    /* for reflection testing (getClasses vs getDeclaredClasses) */
    static public class PublicMemberClass {
        float mBlah;
    }

    /*
     * Dump a variety of class attributes.
     */
    public static <T> void printClassAttrs(Class<T> clazz) {
        System.out.println("***** " + clazz + ":");

        System.out.println("  name: "
            + clazz.getName());
        System.out.println("  canonical: "
            + clazz.getCanonicalName());
        System.out.println("  simple: "
            + clazz.getSimpleName());
        System.out.println("  genericSignature: "
            + getSignatureAttribute(clazz));

        System.out.println("  super: "
            + clazz.getSuperclass());
        System.out.println("  genericSuperclass: "
            + clazz.getGenericSuperclass());
        System.out.println("  declaring: "
            + clazz.getDeclaringClass());
        System.out.println("  enclosing: "
            + clazz.getEnclosingClass());
        System.out.println("  enclosingCon: "
            + clazz.getEnclosingConstructor());
        System.out.println("  enclosingMeth: "
            + clazz.getEnclosingMethod());
        System.out.println("  modifiers: "
            + clazz.getModifiers());
        System.out.println("  package: "
            + clazz.getPackage());

        System.out.println("  declaredClasses: "
            + stringifyTypeArray(clazz.getDeclaredClasses()));
        System.out.println("  member classes: "
            + stringifyTypeArray(clazz.getClasses()));

        System.out.println("  isAnnotation: "
            + clazz.isAnnotation());
        System.out.println("  isAnonymous: "
            + clazz.isAnonymousClass());
        System.out.println("  isArray: "
            + clazz.isArray());
        System.out.println("  isEnum: "
            + clazz.isEnum());
        System.out.println("  isInterface: "
            + clazz.isInterface());
        System.out.println("  isLocalClass: "
            + clazz.isLocalClass());
        System.out.println("  isMemberClass: "
            + clazz.isMemberClass());
        System.out.println("  isPrimitive: "
            + clazz.isPrimitive());
        System.out.println("  isSynthetic: "
            + clazz.isSynthetic());

        System.out.println("  genericInterfaces: "
            + stringifyTypeArray(clazz.getGenericInterfaces()));

        TypeVariable<Class<T>>[] typeParameters = clazz.getTypeParameters();
        System.out.println("  typeParameters: "
            + stringifyTypeArray(typeParameters));
    }

    /*
     * Convert an array of Type into a string.  Start with an array count.
     */
    private static String stringifyTypeArray(Type[] types) {
        List<String> typeStringList = new ArrayList<String>();
        for (Type t : types) {
          typeStringList.add(t.toString());
        }
        // Sort types alphabetically so they're always printed in the same order.
        // For instance, Class.getClasses() does not guarantee any order for the
        // returned Class[].
        Collections.sort(typeStringList);

        StringBuilder stb = new StringBuilder();
        boolean first = true;

        stb.append("[" + types.length + "]");

        for (String typeString : typeStringList) {
            if (first) {
                stb.append(" ");
                first = false;
            } else {
                stb.append(", ");
            }
            stb.append(typeString);
        }

        return stb.toString();
    }
}
