/*
 * Copyright 2005 John G. Wilson
 *
 * 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 groovy.lang;

import java.lang.reflect.Method;
import java.util.List;
import java.util.logging.Logger;

import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.runtime.MetaClassHelper;

/**
 * Base class for meta class implementations. 
 * The meta class is used to invoke methods or to get 
 * fields/properties. For proper initialization of this class 
 * it is not enough to only call the constructor, the
 * initialize() must be called too. The invoke methods should
 * check that initialize() was called. Adding methods is
 * valid unless initilise method was called. Therefore 
 * addNewStaticMethod and addNewInstanceMethod should check that
 * that initilise awas not called before.
 * 
 * 
 * @author John Wilson
 *
 */

public abstract class MetaClass {
    protected static final Logger log = Logger.getLogger(MetaClass.class.getName());
    protected static boolean useReflection = false;
    public static final Object NO_METHOD_FOUND = new Object();
    protected final Class theClass;
    private boolean isGroovyObject;
    
    public static boolean isUseReflection() {
        return MetaClass.useReflection;
    }

    /**
     * Allows reflection to be enabled in situations where bytecode generation
     * of method invocations causes issues.
     *
     * @param useReflection
     */
    public static void setUseReflection(boolean useReflection) {
        MetaClass.useReflection = useReflection;
    }
    
    protected MetaClass(final Class theClass) {
        this.theClass = theClass;
        isGroovyObject = GroovyObject.class.isAssignableFrom(theClass);
    }
    
    public boolean isGroovyObject(){
        return isGroovyObject;
    }
    
    public Object invokeMissingMethod(Object instance, String methodName, Object[] arguments) {
        GroovyObject pogo = (GroovyObject) instance;
        return pogo.invokeMethod(methodName,arguments);
    }
    
    public Object invokeMethod(Object object, String methodName, Object arguments) {
        if (arguments == null) {
            return invokeMethod(object, methodName, MetaClassHelper.EMPTY_ARRAY);
        }
        if (arguments instanceof Tuple) {
            Tuple tuple = (Tuple) arguments;
            return invokeMethod(object, methodName, tuple.toArray());
        }
        if (arguments instanceof Object[]) {
            return invokeMethod(object, methodName, (Object[])arguments);
        }
        else {
            return invokeMethod(object, methodName, new Object[]{arguments});
        }
    }
    
    public Object invokeMethod(Class sender, Object receiver, String methodName, Object[] arguments, boolean isCallToSuper, boolean fromInsideClass){
        return invokeMethod(receiver,methodName,arguments);
    }
    
    public Object getProperty(Class sender, Object receiver, String messageName, boolean useSuper, boolean fromInsideClass) {
        return getProperty(receiver,messageName);
    }
    
    public void setProperty(Class sender, Object receiver, String messageName, Object messageValue, boolean useSuper, boolean fromInsideClass) {
        setProperty(receiver,messageName,messageValue);
    }
    
    public Object getAttribute(Class sender, Object receiver, String messageName, boolean useSuper) {
        return getAttribute(receiver,messageName);
    }
    
    public void setAttribute(Class sender, Object receiver, String messageName, Object messageValue, boolean useSuper, boolean fromInsideClass) {
        setAttribute(receiver,messageName,messageValue);
    }
    
    public abstract Object invokeConstructor(Object[] arguments);
    public abstract Object invokeMethod(Object object, String methodName, Object[] arguments);
    public abstract Object invokeStaticMethod(Object object, String methodName, Object[] arguments);
    public abstract Object getProperty(Object object, String property);
    public abstract void setProperty(Object object, String property, Object newValue);
    public abstract Object getAttribute(Object object, String attribute);
    public abstract void setAttribute(Object object, String attribute, Object newValue);
    /**
     * adds a new instance method to this meta class. Instance
     * methods are able to overwrite the original methods of the
     * class. Calling this method should not be done after 
     * initlise was called.
     * @param method the method to be added
     */
    public abstract void addNewInstanceMethod(Method method);
    /**
     * adds a new static method to this meta class. This is only
     * possible as long as initilise was not called.
     * @param method the method to be added
     */
    public abstract void addNewStaticMethod(Method method);
    /**
     * complete the initlialisation process. After this method
     * is called no methods should be added to the meta class.
     * Invocation of methods or access to fields/proeprties is
     * forbidden unless this method is called. This method 
     * should contain any initialisation code, taking a longer
     * time to complete. An example is the creation of the 
     * Reflector. It is suggested to synchronize this 
     * method.
     */
    public abstract void initialize();
    
    public abstract List getProperties();
    public abstract ClassNode getClassNode();
    public abstract List getMetaMethods();
    
    public abstract List getMethods();
    
    /**
     * Warning, this method will be removed
     * @deprecated use invokeConstructor instead
     */
    public Object invokeConstructorAt(Class at, Object[] arguments) {
        return invokeConstructor(arguments);
    }

    /**
     * Selects a method by name and argument classes. This method
     * does not search for an exact match, it searches for a compatible
     * method. For this the method selection mechanism is used as provided
     * bye the implementation of this MetaClass. pickMethod may or may
     * not used during the method selection process when invoking a method
     * thereis no warranty for that.
     * 
     * @returns a matching MetaMethod or null
     * @throws GroovyRuntimeException if there is more than one matching method
     */
    public abstract MetaMethod pickMethod(String methodName, Class[] arguments);
    
    /**
     * Warning, this method will be removed
     * @deprecated usw pickMethod instead
     */
    protected MetaMethod retrieveMethod(String methodName, Class[] arguments) {
        return pickMethod(methodName,arguments);
    }

}
