package it.mice.voila.runtime.infobar;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.apache.commons.beanutils.PropertyUtils;

/**
 * Implementation of the MessageBroker interface that delegate to a POJO service
 * bean the task to extract messages.
 */
public class GenericDelegatingMessageBrokerImpl implements MessageBroker {

	/**
	 * POJO service bean to delegate message extraction.
	 */
	private Object delegatedMessageBroker = null;
	/**
	 * Method name to call onto the delegated POJO service.
	 */
	private String methodToCall = null;
	/**
	 * The property of the returner entity list to invoke to extract
	 * Collection<String> messages from.
	 */
	private String returnListMessageProperty = null;

	/**
	 * Getter for property delegatedMessageBroker.
	 * 
	 * @return the delegatedMessageBroker
	 */
	public Object getDelegatedMessageBroker() {
		return delegatedMessageBroker;
	}

	/**
	 * Getter for property methodToCall.
	 * 
	 * @return the methodToCall
	 */
	public String getMethodToCall() {
		return methodToCall;
	}

	/**
	 * Getter for property returnListMessageProperty.
	 * 
	 * @return the returnListMessageProperty
	 */
	public String getReturnListMessageProperty() {
		return returnListMessageProperty;
	}

	/**
	 * Setter for property delegatedMessageBroker. 
	 * @param delegatedMessageBroker the delegatedMessageBroker to set
	 */
	public void setDelegatedMessageBroker(Object delegatedMessageBroker) {
		this.delegatedMessageBroker = delegatedMessageBroker;
	}

	/**
	 * Setter for property methodToCall. 
	 * @param methodToCall the methodToCall to set
	 */
	public void setMethodToCall(String methodToCall) {
		this.methodToCall = methodToCall;
	}

	/**
	 * Setter for property returnListMessageProperty. 
	 * @param returnListMessageProperty the returnListMessageProperty to set
	 */
	public void setReturnListMessageProperty(String returnListMessageProperty) {
		this.returnListMessageProperty = returnListMessageProperty;
	}

	/**
	 * getMessages implementation that call delegated POJO service method using
	 * reflections and return the list of messages accessing the indicated
	 * property.
	 * @return message list.
	 */
	@SuppressWarnings("unchecked")
	public Collection<String> getMessages() {
		Collection<String> retList = new ArrayList<String>();
		try {
			Method method = delegatedMessageBroker.getClass().getMethod(
					methodToCall, new Class[] {});
			Collection<Object> result = (Collection<Object>) method.invoke(
					delegatedMessageBroker, new Object[] {});
			if (result != null) {
				Iterator<Object> i = result.iterator();
				while (i.hasNext()) {
					Object element = i.next();
					String message = "";
					if (returnListMessageProperty != null) {
						message = PropertyUtils.getProperty(element,
								returnListMessageProperty).toString();
					} else {
						message = element.toString();
					}
					retList.add(message);
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return retList;
	}

}
