/*
 * 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.
 */

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Comparator;

/**
 * Do some basic tests.
 */
public class BasicTest {

    public static void main(String[] args) {
        Mix proxyMe = new Mix();
        Object proxy = createProxy(proxyMe);

        if (!Proxy.isProxyClass(proxy.getClass()))
            System.err.println("not a proxy class?");
        if (Proxy.getInvocationHandler(proxy) == null)
            System.err.println("ERROR: Proxy.getInvocationHandler is null");

        /* take it for a spin; verifies instanceof constraint */
        Shapes shapes = (Shapes) proxy;
        shapes.circle(3);
        shapes.rectangle(10, 20);
        shapes.blob();
        Quads quads = (Quads) proxy;
        quads.rectangle(15, 25);
        quads.trapezoid(6, 81.18, 4);
        Colors colors = (Colors) proxy;
        colors.red(1.0f);
        colors.blue(777);
        colors.mauve("sorry");
        colors.blob();
        Trace trace = (Trace) proxy;
        trace.getTrace();

        try {
            shapes.upChuck();
            System.out.println("Didn't get expected exception");
        } catch (IndexOutOfBoundsException ioobe) {
            System.out.println("Got expected ioobe");
        }
        try {
            shapes.upCheck();
            System.out.println("Didn't get expected exception");
        } catch (InterruptedException ie) {
            System.out.println("Got expected ie");
        }

        /*
         * Exercise annotations on Proxy classes.  This is mostly to ensure
         * that annotation calls work correctly on generated classes.
         */
        System.out.println("");
        Method[] methods = proxy.getClass().getDeclaredMethods();
        Arrays.sort(methods, new Comparator<Method>() {
          public int compare(Method o1, Method o2) {
            int result = o1.getName().compareTo(o2.getName());
            if (result != 0) {
                return result;
            }
            return o1.getReturnType().getName().compareTo(o2.getReturnType().getName());
          }
        });
        System.out.println("Proxy interfaces: " +
            Arrays.deepToString(proxy.getClass().getInterfaces()));
        System.out.println("Proxy methods: " + Arrays.deepToString(methods));
        Method meth = methods[methods.length -1];
        System.out.println("Decl annos: " + Arrays.deepToString(meth.getDeclaredAnnotations()));
        Annotation[][] paramAnnos = meth.getParameterAnnotations();
        System.out.println("Param annos (" + paramAnnos.length + ") : "
            + Arrays.deepToString(paramAnnos));
        System.out.println("Modifiers: " + meth.getModifiers());
    }

    static Object createProxy(Object proxyMe) {
        /* declare an object that will handle the method calls */
        InvocationHandler handler = new MyInvocationHandler(proxyMe);

        /* create the proxy class */
        Class proxyClass = Proxy.getProxyClass(Shapes.class.getClassLoader(),
                            new Class[] { Quads.class, Colors.class, Trace.class });

        /* create a proxy object, passing the handler object in */
        Object proxy = null;
        try {
            Constructor<Class> cons;
            cons = proxyClass.getConstructor(
                            new Class[] { InvocationHandler.class });
            //System.out.println("Constructor is " + cons);
            proxy = cons.newInstance(new Object[] { handler });
        } catch (NoSuchMethodException nsme) {
            System.err.println("failed: " + nsme);
        } catch (InstantiationException ie) {
            System.err.println("failed: " + ie);
        } catch (IllegalAccessException ie) {
            System.err.println("failed: " + ie);
        } catch (InvocationTargetException ite) {
            System.err.println("failed: " + ite);
        }

        return proxy;
    }
}

/*
 * Some interfaces.
 */
interface Shapes {
    public void circle(int r);
    public int rectangle(int x, int y);

    public String blob();

    public R0base checkMe();
    public void upChuck();
    public void upCheck() throws InterruptedException;
}

interface Quads extends Shapes {
    public int rectangle(int x, int y);
    public int square(int x, int y);
    public int trapezoid(int x, double off, int y);

    public R0a checkMe();
}

/*
 * More interfaces.
 */
interface Colors {
    public int red(float howRed);
    public int green(double howGreen);
    public double blue(int howBlue);
    public int mauve(String apology);

    public String blob();

    public R0aa checkMe();
}

interface Trace {
    public void getTrace();
}

/*
 * Some return types.
 */
class R0base { int mBlah;  }
class R0a extends R0base { int mBlah_a;  }
class R0aa extends R0a { int mBlah_aa;  }


/*
 * A class that implements them all.
 */
class Mix implements Quads, Colors {
    public void circle(int r) {
        System.out.println("--- circle " + r);
    }
    public int rectangle(int x, int y) {
        System.out.println("--- rectangle " + x + "," + y);
        return 4;
    }
    public int square(int x, int y) {
        System.out.println("--- square " + x + "," + y);
        return 4;
    }
    public int trapezoid(int x, double off, int y) {
        System.out.println("--- trap " + x + "," + y + "," + off);
        return 8;
    }
    public String blob() {
        System.out.println("--- blob");
        return "mix";
    }

    public int red(float howRed) {
        System.out.println("--- red " + howRed);
        return 0;
    }
    public int green(double howGreen) {
        System.out.println("--- green " + howGreen);
        return 1;
    }
    public double blue(int howBlue) {
        System.out.println("--- blue " + howBlue);
        return 2.54;
    }
    public int mauve(String apology) {
        System.out.println("--- mauve " + apology);
        return 3;
    }

    public R0aa checkMe() {
        return null;
    }
    public void upChuck() {
        throw new IndexOutOfBoundsException("upchuck");
    }
    public void upCheck() throws InterruptedException {
        throw new InterruptedException("upcheck");
    }
}

/*
 * Invocation handler, defining the implementation of the proxy functions.
 */
class MyInvocationHandler implements InvocationHandler {
    Object mObj;

    public MyInvocationHandler(Object obj) {
        mObj = obj;
    }

    /*
     * This is called when anything gets invoked in the proxy object.
     */
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {

        Object result = null;

        // Trap Object calls.  This is important here to avoid a recursive
        // invocation of toString() in the print statements below.
        if (method.getDeclaringClass() == java.lang.Object.class) {
            //System.out.println("!!! object " + method.getName());
            if (method.getName().equals("toString")) {
                return super.toString();
            } else if (method.getName().equals("hashCode")) {
                return Integer.valueOf(super.hashCode());
            } else if (method.getName().equals("equals")) {
                return Boolean.valueOf(super.equals(args[0]));
            } else {
                throw new RuntimeException("huh?");
            }
        }

        if (method.getDeclaringClass() == Trace.class) {
          if (method.getName().equals("getTrace")) {
            StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
            for (int i = 0; i < stackTrace.length; i++) {
                StackTraceElement ste = stackTrace[i];
                if (ste.getMethodName().equals("getTrace")) {
                  System.out.println(ste.getClassName() + "." + ste.getMethodName() + " " +
                                     ste.getFileName() + ":" + ste.getLineNumber());
                }
            }
            return null;
          }
        }

        if (method.getDeclaringClass() == Trace.class) {
          if (method.getName().equals("getTrace")) {
            StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
            for (int i = 0; i < stackTrace.length; i++) {
                StackTraceElement ste = stackTrace[i];
                if (ste.getMethodName().equals("getTrace")) {
                  System.out.println(ste.getClassName() + "." + ste.getMethodName() + " " +
                                     ste.getFileName() + ":" + ste.getLineNumber());
                }
            }
            return null;
          }
        }

        System.out.println("Invoke " + method);
        if (args == null || args.length == 0) {
            System.out.println(" (no args)");
        } else {
            for (int i = 0; i < args.length; i++)
                System.out.println(" " + i + ": " + args[i]);
        }

        try {
            if (true) {
                result = method.invoke(mObj, args);
            } else {
                result = -1;
            }
            System.out.println("Success: method " + method.getName()
                + " res=" + result);
        } catch (InvocationTargetException ite) {
            throw ite.getTargetException();
        } catch (IllegalAccessException iae) {
            throw new RuntimeException(iae);
        }
        return result;
    }
}
