/*
 * Copyright 2003-2007 the original author or authors.
 *
 * 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 org.codehaus.groovy.runtime.metaclass;

import groovy.lang.*;
import org.codehaus.groovy.reflection.CachedClass;
import org.codehaus.groovy.reflection.CachedField;
import org.codehaus.groovy.reflection.CachedMethod;
import org.codehaus.groovy.reflection.FastArray;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.MetaClassHelper;
import org.codehaus.groovy.runtime.wrappers.Wrapper;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import java.util.logging.Level;

/**
 * A Metaclass for closures generated by the Groovy compiler. These classes
 * have special characteristics this MetaClass uses. One of these is that a
 * generated Closure has only additional doCall methods, all other methods
 * are in the Closure class as well. To use this fact this MetaClass uses
 * a MetaClass for Closure as static field And delegates calls to this
 * MetaClass if needed. This allows a lean implementation for this MetaClass.
 * Multiple generated closures will then use the same MetaClass for Closure.
 * For static dispatching this class uses the MetaClass of Class, again
 * all isntances of this class will share that MetaClass. The Class MetaClass
 * is initialized lazy, because most operations do not need this MetaClass.
 * <p/>
 * The Closure and Class MetaClasses are not replaceable.
 * <p/>
 * This MetaClass is for internal usage only!
 *
 * @author Jochen Theodorou
 * @since 1.1
 */
public final class ClosureMetaClass extends MetaClassImpl {
    private boolean initialized;
    private final FastArray closureMethods = new FastArray(3);
    private Map attributes = new HashMap();
    private MethodChooser chooser;
    private volatile boolean attributeInitDone = false;

    private static final MetaClassImpl CLOSURE_METACLASS;
    private static MetaClassImpl classMetaClass;
    private static final Object[] EMPTY_ARGUMENTS = {};
    private static final String CLOSURE_CALL_METHOD = "call";
    private static final String CLOSURE_DO_CALL_METHOD = "doCall";
    private static final String CLOSURE_CURRY_METHOD = "curry";

    static {
        CLOSURE_METACLASS = new MetaClassImpl(Closure.class);
        CLOSURE_METACLASS.initialize();
    }

    private static synchronized MetaClass getStaticMetaClass() {
        if (classMetaClass == null) {
            classMetaClass = new MetaClassImpl(Class.class);
            classMetaClass.initialize();
        }
        return classMetaClass;
    }

    private static interface MethodChooser {
        Object chooseMethod(Class[] arguments, boolean coerce);
    }

    private static class StandardClosureChooser implements MethodChooser {
        private final MetaMethod doCall0;
        private final MetaMethod doCall1;

        StandardClosureChooser(MetaMethod m0, MetaMethod m1) {
            doCall0 = m0;
            doCall1 = m1;
        }

        public Object chooseMethod(Class[] arguments, boolean coerce) {
            if (arguments.length == 0) return doCall0;
            if (arguments.length == 1) return doCall1;
            return null;
        }
    }

    private static class NormalMethodChooser implements MethodChooser {
        private final FastArray methods;
        final Class theClass;

        NormalMethodChooser(Class theClass, FastArray methods) {
            this.theClass = theClass;
            this.methods = methods;
        }

        public Object chooseMethod(Class[] arguments, boolean coerce) {
            if (arguments.length == 0) {
                return MetaClassHelper.chooseEmptyMethodParams(methods);
            } else if (arguments.length == 1 && arguments[0] == null) {
                return MetaClassHelper.chooseMostGeneralMethodWith1NullParam(methods);
            } else {
                List matchingMethods = new ArrayList();

                final int len = methods.size();
                final Object[] data = methods.getArray();
                for (int i = 0; i != len; ++i) {
                    Object method = data[i];

                    // making this false helps find matches
                    if (MetaClassHelper.isValidMethod(method, arguments, coerce)) {
                        matchingMethods.add(method);
                    }
                }
                if (matchingMethods.isEmpty()) {
                    return null;
                } else if (matchingMethods.size() == 1) {
                    return matchingMethods.get(0);
                }
                return chooseMostSpecificParams(CLOSURE_DO_CALL_METHOD, matchingMethods, arguments);
            }
        }

        private Object chooseMostSpecificParams(String name, List matchingMethods, Class[] arguments) {
            long matchesDistance = -1;
            LinkedList matches = new LinkedList();
            for (Iterator iter = matchingMethods.iterator(); iter.hasNext();) {
                Object method = iter.next();
                Class[] paramTypes = MetaClassHelper.getParameterTypes(method).getNativeParameterTypes();
                if (!MetaClassHelper.parametersAreCompatible(arguments, paramTypes)) continue;
                long dist = MetaClassHelper.calculateParameterDistance(arguments, paramTypes);
                if (dist == 0) return method;
                if (matches.isEmpty()) {
                    matches.add(method);
                    matchesDistance = dist;
                } else if (dist < matchesDistance) {
                    matchesDistance = dist;
                    matches.clear();
                    matches.add(method);
                } else if (dist == matchesDistance) {
                    matches.add(method);
                }

            }
            if (matches.size() == 1) {
                return matches.getFirst();
            }
            if (matches.isEmpty()) {
                return null;
            }

            //more than one matching method found --> ambigous!
            String msg = "Ambiguous method overloading for method ";
            msg += theClass.getName() + "#" + name;
            msg += ".\nCannot resolve which method to invoke for ";
            msg += InvokerHelper.toString(arguments);
            msg += " due to overlapping prototypes between:";
            for (Iterator iter = matches.iterator(); iter.hasNext();) {
                CachedClass[] types = MetaClassHelper.getParameterTypes(iter.next()).getParameterTypes();
                msg += "\n\t" + InvokerHelper.toString(types);
            }
            throw new GroovyRuntimeException(msg);
        }
    }


    public ClosureMetaClass(MetaClassRegistry registry, Class theClass) {
        super(registry, theClass);
    }

    public MetaProperty getMetaProperty(String name) {
        return CLOSURE_METACLASS.getMetaProperty(name);
    }

    private void unwrap(Object[] arguments) {
        for (int i = 0; i != arguments.length; i++) {
            if (arguments[i] instanceof Wrapper) {
                arguments[i] = ((Wrapper) arguments[i]).unwrap();
            }
        }
    }

    private MetaMethod pickClosureMethod(Class[] argClasses) {
        Object answer = chooser.chooseMethod(argClasses, false);
        return (MetaMethod) answer;
    }

    private MetaMethod getDelegateMethod(Closure closure, Object delegate, String methodName, Class[] argClasses) {
        if (delegate == closure || delegate == null) return null;
        MetaClass delegateMetaClass;
        if (delegate instanceof Class) {
            delegateMetaClass = registry.getMetaClass((Class)delegate);
            return delegateMetaClass.getStaticMetaMethod(methodName, argClasses);
        }
        else {
            delegateMetaClass = lookupObjectMetaClass(delegate);
            return delegateMetaClass.pickMethod(methodName, argClasses);
        }
    }

    public Object invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass) {
        checkInitalised();
        if (object == null) {
            throw new NullPointerException("Cannot invoke method: " + methodName + " on null object");
        }
        if (LOG.isLoggable(Level.FINER)) {
            MetaClassHelper.logMethodCall(object, methodName, originalArguments);
        }

        final Object[] arguments = makeArguments(originalArguments, methodName); 
        final Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
        unwrap(arguments);

        MetaMethod method;
        final Closure closure = (Closure) object;

        if (CLOSURE_DO_CALL_METHOD.equals(methodName) || CLOSURE_CALL_METHOD.equals(methodName)) {
            method = pickClosureMethod(argClasses);
            if (method==null && arguments.length==1 && arguments[0] instanceof List) {
                Object[] newArguments = ((List) arguments[0]).toArray();
                Class[] newArgClasses = MetaClassHelper.convertToTypeArray(newArguments);
                method = pickClosureMethod(newArgClasses);
                if (method!=null) {
                    method = new TransformMetaMethod(method) {
                        public Object invoke(Object object, Object[] arguments) {
                            Object firstArgument = arguments[0];
                            List list = (List) firstArgument;
                            arguments = list.toArray();
                            return super.invoke(object, arguments);
                        }
                    };
                }
            }
            if (method==null) throw new MissingMethodException(methodName, theClass, arguments, false);
        } else if (CLOSURE_CURRY_METHOD.equals(methodName)) {
            return closure.curry(arguments);
        } else {
            method = CLOSURE_METACLASS.pickMethod(methodName, argClasses);
        }
 
        if (method != null) return MetaClassHelper.doMethodInvoke(object, method, arguments);

        MissingMethodException last = null;
        Object callObject = object;
        if (method == null) {
            final Object owner = closure.getOwner();
            final Object delegate = closure.getDelegate();
            final Object thisObject = closure.getThisObject();
            final int resolveStrategy = closure.getResolveStrategy();
            boolean invokeOnDelegate = false;
            boolean invokeOnOwner = false;
            boolean ownerFirst = true;

            switch (resolveStrategy) {
                case Closure.TO_SELF:
                    break;
                case Closure.DELEGATE_ONLY:
                    method = getDelegateMethod(closure, delegate, methodName, argClasses);
                    callObject = delegate;
                    if (method == null) {
                        invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject);
                    }
                    break;
                case Closure.OWNER_ONLY:
                    method = getDelegateMethod(closure, owner, methodName, argClasses);
                    callObject = owner;
                    if (method == null) {
                        invokeOnOwner = owner != closure && (owner instanceof GroovyObject);
                    }

                    break;
                case Closure.DELEGATE_FIRST:
                    method = getDelegateMethod(closure, delegate, methodName, argClasses);
                    callObject = delegate;
                    if (method == null) {
                        method = getDelegateMethod(closure, owner, methodName, argClasses);
                        callObject = owner;
                    }
                    if (method == null) {
                        invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject);
                        invokeOnOwner = owner != closure && (owner instanceof GroovyObject);
                        ownerFirst = false;
                    }
                    break;
                default: // owner first
                    // owner first means we start with the outer most owner that is not a generated closure
                    // this owner is equal to the this object, so we check that one first.                    
                    method = getDelegateMethod(closure, thisObject, methodName, argClasses);
                    callObject = thisObject;
                    if (method == null) {
                        //try finding a delegate that has that method... we start from 
                        // outside building a stack and try each delegate
                        LinkedList list = new LinkedList();
                        for (Object current = closure; current!=thisObject; ) {
                            Closure currentClosure = (Closure) current; 
                            if (currentClosure.getDelegate()!=null) list.add(current);
                            current=currentClosure.getOwner();
                        }

                        while (!list.isEmpty() && method==null) {
                            Closure closureWithDelegate = (Closure) list.removeLast();
                            Object currentDelegate = closureWithDelegate.getDelegate();
                            method = getDelegateMethod(closureWithDelegate,currentDelegate,methodName,argClasses);
                            callObject = currentDelegate;
                        }
                    }
                    if (method == null) {
                        invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject);
                        invokeOnOwner = owner != closure && (owner instanceof GroovyObject);
                    }
            }
            if (method == null && (invokeOnOwner || invokeOnDelegate)) {
                try {
                    if (ownerFirst) {
                        return invokeOnDelegationObjects(invokeOnOwner, owner, invokeOnDelegate, delegate, methodName, arguments);
                    } else {
                        return invokeOnDelegationObjects(invokeOnDelegate, delegate, invokeOnOwner, owner, methodName, arguments);
                    }
                } catch (MissingMethodException mme) {
                    last = mme;
                }
            }
        }

        if (method != null) {
            return MetaClassHelper.doMethodInvoke(callObject, method, arguments);
        } else {
            // if no method was found, try to find a closure defined as a field of the class and run it
            Object value = null;
            try {
                value = this.getProperty(object, methodName);
            } catch (MissingPropertyException mpe) {
                // ignore
            }
            if (value instanceof Closure) {  // This test ensures that value != this If you ever change this ensure that value != this
                Closure cl = (Closure) value;
                MetaClass delegateMetaClass = cl.getMetaClass();
                return delegateMetaClass.invokeMethod(cl.getClass(), closure, CLOSURE_DO_CALL_METHOD, originalArguments, false, fromInsideClass);
            }
        }

        if (last != null) throw last;
        throw new MissingMethodException(methodName, theClass, arguments, false);
    }

    private Object[] makeArguments(Object[] arguments, String methodName) {
        if (arguments == null) return EMPTY_ARGUMENTS;
        if (CLOSURE_CALL_METHOD.equals(methodName)) {
            if (arguments.length==1 && arguments[0] instanceof Object[]) {
                return (Object[]) arguments[0];
            }
        }
        return arguments;
    }

    private Object invokeOnDelegationObjects(
            boolean invoke1, Object o1,
            boolean invoke2, Object o2,
            String methodName, Object[] args) {
        MissingMethodException first = null;
        if (invoke1) {
            GroovyObject go = (GroovyObject) o1;
            try {
                return go.invokeMethod(methodName, args);
            } catch (MissingMethodException mme) {
                first = mme;
            }
        }
        if (invoke2) {
            GroovyObject go = (GroovyObject) o2;
            try {
                return go.invokeMethod(methodName, args);
            } catch (MissingMethodException mme) {
                if (first == null) first = mme;
            }
        }
        throw first;
    }

    private synchronized void initAttributes() {
        if (!attributes.isEmpty()) return;
        attributes.put("!", null); // just a dummy for later
        CachedField[] fieldArray = theCachedClass.getFields();
        for (int i = 0; i < fieldArray.length; i++) {
            MetaFieldProperty mfp = MetaFieldProperty.create(fieldArray[i]);
            attributes.put(fieldArray[i].getName(), mfp);
        }
        attributeInitDone = !attributes.isEmpty();
    }

    public synchronized void initialize() {
        if (!isInitialized()) {
            CachedMethod[] methodArray = theCachedClass.getMethods();
            synchronized (theCachedClass) {
                for (int i = 0; i < methodArray.length; i++) {
                    final CachedMethod cachedMethod = methodArray[i];
                    Method reflectionMethod = cachedMethod.cachedMethod;
                    if (!reflectionMethod.getName().equals(CLOSURE_DO_CALL_METHOD)) continue;
                    MetaMethod method = cachedMethod.getReflectionMetaMethod();
                    closureMethods.add(method);
                }
            }
            assignMethodChooser();

            initialized = true;
        }
    }

    private void assignMethodChooser() {
        if (closureMethods.size() == 1) {
            final MetaMethod doCall = (MetaMethod) closureMethods.get(0);
            final CachedClass[] c = doCall.getParameterTypes();
            int length = c.length;
            if (length == 0) {
                // no arg method
                chooser = new MethodChooser() {
                    public Object chooseMethod(Class[] arguments, boolean coerce) {
                        if (arguments.length == 0) return doCall;
                        return null;
                    }
                };
            } else {
                if (length == 1 && c[0].getCachedClass() == Object.class) {
                    // Object fits all, so simple dispatch rule here
                    chooser = new MethodChooser() {
                        public Object chooseMethod(Class[] arguments, boolean coerce) {
                            // <2, because foo() is same as foo(null)
                            if (arguments.length < 2) return doCall;
                            return null;
                        }
                    };
                } else {
                    boolean allObject = true;
                    for (int i = 0; i < c.length - 1; i++) {
                        if (c[i].getCachedClass() != Object.class) {
                            allObject = false;
                            break;
                        }
                    }
                    if (allObject && c[c.length - 1].getCachedClass() == Object.class) {
                        // all arguments are object, so test only if argument number is correct
                        chooser = new MethodChooser() {
                            public Object chooseMethod(Class[] arguments, boolean coerce) {
                                if (arguments.length == c.length) return doCall;
                                return null;
                            }
                        };
                    } else {
                        if (allObject && c[c.length - 1].getCachedClass() == Object[].class) {
                            // all arguments are Object but last, which is a vargs argument, that
                            // will fit all, so jsut test if the number of argument is equal or
                            // more than the parameters we have.
                            final int minimumLength = c.length - 2;
                            chooser = new MethodChooser() {
                                public Object chooseMethod(Class[] arguments, boolean coerce) {
                                    if (arguments.length > minimumLength) return doCall;
                                    return null;
                                }
                            };
                        } else {
                            // general case for single method
                            chooser = new MethodChooser() {
                                public Object chooseMethod(Class[] arguments, boolean coerce) {
                                    if (MetaClassHelper.isValidMethod(doCall, arguments, coerce)) {
                                        return doCall;
                                    }
                                    return null;
                                }
                            };
                        }
                    }
                }
            }
        } else if (closureMethods.size() == 2) {
            MetaMethod m0 = null, m1 = null;
            for (int i = 0; i != closureMethods.size(); ++i) {
                MetaMethod m = (MetaMethod) closureMethods.get(i);
                CachedClass[] c = m.getParameterTypes();
                if (c.length == 0) {
                    m0 = m;
                } else {
                    if (c.length == 1 && c[0].getCachedClass() == Object.class) {
                        m1 = m;
                    }
                }
            }
            if (m0 != null && m1 != null) {
                // standard closure (2 methods because "it" is with default null)
                chooser = new StandardClosureChooser(m0, m1);
            }
        }
        if (chooser == null) {
            // standard chooser for cases if it is not a single method and if it is
            // not the standard closure.
            chooser = new NormalMethodChooser(theClass, closureMethods);
        }
    }

    private void generateReflector() {
//        if (GroovySystem.isUseReflection())
//          return;
//
//        reflector = ((MetaClassRegistryImpl) registry).loadReflector(theClass, closureMethods);
//        if (reflector == null) {
//            throw new RuntimeException("Should have a reflector for " + theClass.getName());
//        }
//        // lets set the reflector on all the methods
//        for (Iterator iter = closureMethods.iterator(); iter.hasNext();) {
//            StdMetaMethod metaMethod = (StdMetaMethod) iter.next();
//            metaMethod.setReflector(reflector);
//        }
    }

    private MetaClass lookupObjectMetaClass(Object object) {
        if (object instanceof GroovyObject) {
            GroovyObject go = (GroovyObject) object;
            return go.getMetaClass();
        }
        Class ownerClass = object.getClass();
        if (ownerClass == Class.class) ownerClass = (Class) object;
        MetaClass metaClass = registry.getMetaClass(ownerClass);
        return metaClass;
    }

    public List getMethods() {
        List answer = CLOSURE_METACLASS.getMetaMethods();
        answer.addAll(closureMethods.toList());
        return answer;
    }

    public List getMetaMethods() {
        return CLOSURE_METACLASS.getMetaMethods();
    }

    public List getProperties() {
        return CLOSURE_METACLASS.getProperties();
    }

    public MetaMethod pickMethod(String name, Class[] argTypes) {
        if (argTypes == null) argTypes = EMPTY_CLASS_ARRAY;
        if (name.equals(CLOSURE_CALL_METHOD) || name.equals(CLOSURE_DO_CALL_METHOD)) {
            return pickClosureMethod(argTypes);
        }
        return CLOSURE_METACLASS.getMetaMethod(name, argTypes);
    }

    public MetaMethod retrieveStaticMethod(String methodName, Class[] arguments) {
        return null;
    }

    protected boolean isInitialized() {
        return initialized;
    }

    public MetaMethod getStaticMetaMethod(String name, Object[] args) {
        return CLOSURE_METACLASS.getStaticMetaMethod(name, args);
    }

    public MetaMethod getStaticMetaMethod(String name, Class[] argTypes) {
        return CLOSURE_METACLASS.getStaticMetaMethod(name, argTypes);
    }

    public Object getProperty(Class sender, Object object, String name, boolean useSuper, boolean fromInsideClass) {
        if (object instanceof Class) {
            return getStaticMetaClass().getProperty(sender, object, name, useSuper, fromInsideClass);
        } else {
            return CLOSURE_METACLASS.getProperty(sender, object, name, useSuper, fromInsideClass);
        }
    }

    public Object getAttribute(Class sender, Object object, String attribute, boolean useSuper, boolean fromInsideClass) {
        if (object instanceof Class) {
            return getStaticMetaClass().getAttribute(sender, object, attribute, useSuper);
        } else {
            if (!attributeInitDone) initAttributes();
            MetaFieldProperty mfp = (MetaFieldProperty) attributes.get(attribute);
            if (mfp == null) {
                return CLOSURE_METACLASS.getAttribute(sender, object, attribute, useSuper);
            } else {
                return mfp.getProperty(object);
            }
        }
    }

    public void setAttribute(Class sender, Object object, String attribute,
                             Object newValue, boolean useSuper, boolean fromInsideClass) {
        if (object instanceof Class) {
            getStaticMetaClass().setAttribute(sender, object, attribute, newValue, useSuper, fromInsideClass);
        } else {
            if (!attributeInitDone) initAttributes();
            MetaFieldProperty mfp = (MetaFieldProperty) attributes.get(attribute);
            if (mfp == null) {
                CLOSURE_METACLASS.setAttribute(sender, object, attribute, newValue, useSuper, fromInsideClass);
            } else {
                mfp.setProperty(object, newValue);
            }
        }
    }

    public Object invokeStaticMethod(Object object, String methodName, Object[] arguments) {
        return getStaticMetaClass().invokeMethod(Class.class, object, methodName, arguments, false, false);
    }

    public void setProperty(Class sender, Object object, String name, Object newValue, boolean useSuper, boolean fromInsideClass) {
        if (object instanceof Class) {
            getStaticMetaClass().setProperty(sender, object, name, newValue, useSuper, fromInsideClass);
        } else {
            CLOSURE_METACLASS.setProperty(sender, object, name, newValue, useSuper, fromInsideClass);
        }
    }

    public MetaMethod getMethodWithoutCaching(Class sender, String methodName, Class[] arguments, boolean isCallToSuper) {
        throw new UnsupportedOperationException();
    }

    public void setProperties(Object bean, Map map) {
        throw new UnsupportedOperationException();
    }

    private Object invokeConstructor(Class at, Object[] arguments) {
        throw new UnsupportedOperationException();
    }

    public void addMetaBeanProperty(MetaBeanProperty mp) {
        throw new UnsupportedOperationException();
    }

    public void addMetaMethod(MetaMethod method) {
        throw new UnsupportedOperationException();
    }

    public void addNewInstanceMethod(Method method) {
        throw new UnsupportedOperationException();
    }

    public void addNewStaticMethod(Method method) {
        throw new UnsupportedOperationException();
    }

    public Constructor retrieveConstructor(Class[] arguments) {
        throw new UnsupportedOperationException();
    }
}
