/*
 * 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: " +
            Main.replaceProxyClassNamesForOutput(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 });
        Main.registerProxyClassName(proxyClass.getCanonicalName());

        /* 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")) {
                  String outputClassName = Main.replaceProxyClassNamesForOutput(ste.getClassName());
                  System.out.println(outputClassName + "." + 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")) {
                  String outputClassName = Main.replaceProxyClassNamesForOutput(ste.getClassName());
                  System.out.println(outputClassName + "." + 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;
    }
}
