/*
 * Copyright 2004-2005 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.grails.commons.metaclass;

import java.beans.IntrospectionException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;



/**
 * InvokerHelper.getInstance().getMetaRegistry().setMetaClass(Foo.class,myFooMetaClass)
 * 
 * @author Steven Devijver
 * @since Aug 7, 2005
 */
public abstract class AbstractDynamicMethods implements DynamicMethods {

	private Collection dynamicMethodInvocations = null;
	private Collection staticMethodInvocations = null;
	private Map dynamicProperties = null;
	private Class clazz = null;
	
	private static final Log LOG = LogFactory.getLog(AbstractDynamicMethods.class);
	
	public AbstractDynamicMethods(Class theClass)
			throws IntrospectionException {
		this(theClass, true);		
	}
	
	public AbstractDynamicMethods(Class theClass, boolean inRegistry)
	throws IntrospectionException {
			super();
			new DelegatingMetaClass(theClass, this, inRegistry);
			this.clazz = theClass;
			this.dynamicMethodInvocations = new ArrayList();
			this.staticMethodInvocations = new ArrayList();
			this.dynamicProperties = new HashMap();
	}	

	/* (non-Javadoc)
	 * @see org.codehaus.groovy.grails.metaclass.DynamicMethods#addDynamicMethodInvocation(org.codehaus.groovy.grails.metaclass.DynamicMethodInvocation)
	 */
	public void addDynamicMethodInvocation(DynamicMethodInvocation methodInvocation) {		
		this.dynamicMethodInvocations.add(methodInvocation);
	}
	
	/* (non-Javadoc)
	 * @see org.codehaus.groovy.grails.metaclass.DynamicMethods#addStaticMethodInvocation(org.codehaus.groovy.grails.metaclass.StaticMethodInvocation)
	 */
	public void addStaticMethodInvocation(StaticMethodInvocation methodInvocation) {
		this.staticMethodInvocations.add(methodInvocation);
	}
	
	/* (non-Javadoc)
	 * @see org.codehaus.groovy.grails.metaclass.DynamicMethods#addDynamicProperty(org.codehaus.groovy.grails.metaclass.DynamicProperty)
	 */
	public void addDynamicProperty(DynamicProperty property) {
		this.dynamicProperties.put(property.getPropertyName(), property);
	}
	
	/* (non-Javadoc)
	 * @see org.codehaus.groovy.grails.metaclass.DynamicMethods#getProperty(java.lang.Object, java.lang.String, org.codehaus.groovy.grails.metaclass.InvocationCallback)
	 */
	public Object getProperty(Object object, String propertyName, InvocationCallback callback) {		
		DynamicProperty getter = (DynamicProperty)this.dynamicProperties.get(propertyName);
		if (getter != null && getter.isPropertyMatch(propertyName)) {
			callback.markInvoked();
			return getter.get(object);
		}
		return null;		
	}
	/* (non-Javadoc)
	 * @see org.codehaus.groovy.grails.metaclass.DynamicMethods#setProperty(java.lang.Object, java.lang.String, java.lang.Object, org.codehaus.groovy.grails.metaclass.InvocationCallback)
	 */
	public void setProperty(Object object, String propertyName,Object newValue, InvocationCallback callback) {
		DynamicProperty setter = (DynamicProperty)this.dynamicProperties.get(propertyName);
		if (setter != null && setter.isPropertyMatch(propertyName)) {
			callback.markInvoked();
			setter.set(object,newValue);
		}		
	}	
	/* (non-Javadoc)
	 * @see org.codehaus.groovy.grails.metaclass.DynamicMethods#invokeMethod(java.lang.Object, java.lang.String, java.lang.Object[], org.codehaus.groovy.grails.metaclass.InvocationCallback)
	 */
	public Object invokeMethod(Object object, String methodName,
		Object[] arguments, InvocationCallback callback) {
		if(LOG.isTraceEnabled()) {
			LOG.trace("[DynamicMethods] Attempting invocation of dynamic method ["+methodName+"] on target ["+object+"] with arguments ["+Arrays.toString( arguments )+"]");			
		}		
		for (Iterator iter = this.dynamicMethodInvocations.iterator(); iter.hasNext();) {
			DynamicMethodInvocation methodInvocation = (DynamicMethodInvocation)iter.next();
			if (methodInvocation.isMethodMatch(methodName)) {
				if(LOG.isTraceEnabled()) {
					LOG.trace("[DynamicMethods] Dynamic method matched, marking and invoking");			
				}				
				callback.markInvoked();
				return methodInvocation.invoke(object, arguments);
			}
		}
		return null;
	}
	
	/* (non-Javadoc)
	 * @see org.codehaus.groovy.grails.metaclass.DynamicMethods#invokeStaticMethod(java.lang.Object, java.lang.String, java.lang.Object[], org.codehaus.groovy.grails.metaclass.InvocationCallback)
	 */
	public Object invokeStaticMethod(Object object, String methodName,
			Object[] arguments, InvocationCallback callBack) {
		if(LOG.isTraceEnabled()) {
			LOG.trace("[DynamicMethods] Attempting invocation of dynamic static method ["+methodName+"] on target ["+object+"] with arguments ["+Arrays.toString( arguments )+"]");
			LOG.trace("[DynamicMethods] Registered dynamic static methods: ["+this.staticMethodInvocations+"]");
		}
		for (Iterator iter = this.staticMethodInvocations.iterator(); iter.hasNext();) {
			StaticMethodInvocation methodInvocation = (StaticMethodInvocation)iter.next();
			if (methodInvocation.isMethodMatch(methodName)) {
				if(LOG.isTraceEnabled()) {
					LOG.trace("[DynamicMethods] Static method matched, marking and invoking");			
				}				
				callBack.markInvoked();
				return methodInvocation.invoke(this.clazz, methodName, arguments);
			}
		}
		return null;
	}

	public DynamicProperty getDynamicProperty(String propertyName) {
		return (DynamicProperty)this.dynamicProperties.get(propertyName);
	}
}
