/*******************************************************************************
 * Copyright (c) 2007 IBM Corporation and Others
 * 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:
 *    Hisashi MIYASHITA - initial API and implementation
 *******************************************************************************/

package org.eclipse.actf.examples.aibrowser.launcher.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Mirror {
    final private Class class1;
    final private Object object;

    public Object getObject() {
        return object;
    }

    private Class[] parseMethodSignature(String params) {
        String[] paramArray;

        paramArray = params.split(", *");
        Class[] cs = new Class[paramArray.length];
        try {
            for (int i = 0; i < paramArray.length; i++) {
                if ("int".equals(paramArray[i])) {
                    cs[i] = java.lang.Integer.TYPE;
                } else if ("short".equals(paramArray[i])) {
                    cs[i] = java.lang.Short.TYPE;
                } else if ("long".equals(paramArray[i])) {
                    cs[i] = java.lang.Long.TYPE;
                } else if ("char".equals(paramArray[i])) {
                    cs[i] = java.lang.Character.TYPE;
                } else if ("boolean".equals(paramArray[i])) {
                    cs[i] = java.lang.Boolean.TYPE;
                } else if ("byte".equals(paramArray[i])) {
                    cs[i] = java.lang.Byte.TYPE;
                } else if ("float".equals(paramArray[i])) {
                    cs[i] = java.lang.Float.TYPE;
                } else if ("double".equals(paramArray[i])) {
                    cs[i] = java.lang.Double.TYPE;
                } else {
                    cs[i] = Class.forName(paramArray[i], true, class1.getClassLoader());
                }
            }
        } catch (ClassNotFoundException e) {
            return null;
        }

        return cs;
    }

    public Method getMethod(String signature) {
        String name;
        Class[] params = null;
        int posParam = signature.indexOf('(');
        if (posParam == -1) {
            name = signature;
        } else {
            name = signature.substring(0, posParam);
            int posParamEnd = signature.lastIndexOf(')');
            if (posParamEnd == -1) return null;
            params = parseMethodSignature(signature.substring(posParam + 1, posParamEnd));
            if (params == null) return null;
        }

        Method m = null;
        for (Class c = class1; c != null; c = c.getSuperclass()) {
            try {
                if (params == null) {
                    Method[] ms = c.getDeclaredMethods();
                    for (int i = 0; i < ms.length; i++) {
                        if (name.equals(ms[i].getName())) {
                            m = ms[i];
                        }
                    }
                } else {
                    m = c.getDeclaredMethod(name, params);
                }
            } catch (SecurityException e) {
                continue;
            } catch (NoSuchMethodException e) {
                continue;
            }
            if (m != null) {
                m.setAccessible(true);
                return m;
            }
        }

        return null;
    }

    public Object invoke(String signature, Object[] params) throws Exception {
        Method m = getMethod(signature);
        return m.invoke(object, params);
    }

    public Field getField(String name) {
        Field f;

        for (Class c = class1; c != null; c = c.getSuperclass()) {
            try {
                f = c.getDeclaredField(name);
            } catch (SecurityException e) {
                continue;
            } catch (NoSuchFieldException e) {
                continue;
            }
            if (f != null) {
                f.setAccessible(true);
                return f;
            }
        }
        return null;
    }

    public Object getFieldObject(String name) throws IllegalAccessException {
        return getField(name).get(object);
    }

    static private boolean isParamAccept(Class cp, Class c) {
        if (cp.isAssignableFrom(c)) return true;

        if ((java.lang.Integer.TYPE == cp)
            && java.lang.Integer.class.equals(c))
            return true;
        if ((java.lang.Short.TYPE == cp)
            && java.lang.Short.class.equals(c))
            return true;
        if ((java.lang.Long.TYPE == cp)
            && java.lang.Long.class.equals(c))
            return true;
        if ((java.lang.Character.TYPE == cp)
            && java.lang.Character.class.equals(c))
            return true;
        if ((java.lang.Boolean.TYPE == cp)
            && java.lang.Boolean.class.equals(c))
            return true;
        if ((java.lang.Byte.TYPE == cp)
            && java.lang.Byte.class.equals(c))
            return true;
        if ((java.lang.Float.TYPE == cp)
            && java.lang.Float.class.equals(c))
        if ((java.lang.Double.TYPE == cp)
            && java.lang.Double.class.equals(c))
            return true;

        return false;
    }

    public Constructor findConstructor(Object[] params) {
        Constructor[] cs = class1.getDeclaredConstructors();

        nextConstructor:
        for (int i = 0; i < cs.length; i++) {
            Class[] cParams = cs[i].getParameterTypes();
            if (params == null) {
                if (cParams.length == 0) return cs[i];
                continue nextConstructor;
            }
            if (cParams.length != params.length) continue nextConstructor;;
            for (int j = 0; j < params.length; j++) {
                if (!isParamAccept(cParams[j], params[j].getClass())) continue nextConstructor;
            }
            return cs[i];
        }

        return null;
    }

    public Object newInstance(Object[] params)
    	throws InvocationTargetException, IllegalAccessException, InstantiationException {
        return findConstructor(params).newInstance(params);
    }

    public Mirror(String className) throws ClassNotFoundException {
        this.class1 = Class.forName(className);
        this.object = null;
    }

    public Mirror(Class cls) {
        this.class1 = cls;
        this.object = null;
    }

    public Mirror(Object object) {
        this.class1 = object.getClass();
        this.object = object;
    }

    public Mirror(String className, Object[] params)
    	throws ClassNotFoundException,
               InvocationTargetException, IllegalAccessException, InstantiationException {
        this.class1 = Class.forName(className);
        this.object = newInstance(params);
    }

    public static void main(String[] args) throws Exception {
        Mirror miS = new Mirror("java.lang.String");

        System.out.println("java.lang.String.charAt:"
                           + miS.getMethod("charAt"));
        System.out.println("java.lang.String.indexOf(int,int):"
                           + miS.getMethod("indexOf(int, int)"));

        Mirror miS2 = new Mirror("java.lang.String", new Object[]{"test string"});
        System.out.println("String instanciation test:" + miS2.getObject());

        Mirror miI = new Mirror("java.lang.Integer", new Object[]{new Integer(100)});
        System.out.println("Integer instanciation test:" + miI.getObject());
    }
}
