package eu.dnetlib.contract.spring.beans;

import java.util.List;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;

import eu.dnetlib.contract.runner.InvokerData;


/**
 * {@link InvokerData} bean definition parser.
 * @author mhorst
 *
 */
public class InvokerDataBeanDefinitionParser extends AbstractContractBeanDefinitionParser {

	public static final String METHOD_NAME_ATTR_NAME	= "methodName";
	public static final String TARGET_REF_ATTR_NAME		= "targetRef";
		
	public static final String ARGS_ELEMENT_NAME		= "args";
	public static final String TARGET_ELEMENT_NAME		= "target";
	public static final String PARAM_TYPES_ELEMENT_NAME	= "parameter-types";
	public static final String PARAM_TYPES_PROP_NAME	= "parameterTypes";

	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder)
	 */
	@Override
	protected void doParse(Element element, ParserContext parserContext,
			BeanDefinitionBuilder builder) {
		super.doParse(element, parserContext, builder);
		
//		handles method name
		String methodName = element.getAttribute(METHOD_NAME_ATTR_NAME);
		if (isAttributeSet(methodName)) {
			builder.addPropertyValue(METHOD_NAME_ATTR_NAME, methodName);
		}
//		handles target
		String targetRef = element.getAttribute(TARGET_REF_ATTR_NAME);
		if (isAttributeSet(targetRef)) {
			builder.addPropertyReference("target", targetRef);
		} else {
//			if ref is not set processing target element
			Element targetElement = DomUtils.getChildElementByTagName(element,TARGET_ELEMENT_NAME);
			if (targetElement!=null) {
				setFirstChildAsProperty(targetElement, parserContext, builder, TARGET_ELEMENT_NAME);
			}
		}
		
//		handles attrs array
		Element attrsElement = DomUtils.getChildElementByTagName(element,ARGS_ELEMENT_NAME);
		if (attrsElement!=null) {
			List<?> list = parserContext.getDelegate().parseListElement((Element) attrsElement,
				builder.getBeanDefinition());
			builder.addPropertyValue(ARGS_ELEMENT_NAME, list);
		}
		
//		handles parameter types array
		Element attrsStrictCheckElement = DomUtils.getChildElementByTagName(element,
				PARAM_TYPES_ELEMENT_NAME);
		if (attrsStrictCheckElement!=null) {
			List<?> list = parserContext.getDelegate().parseListElement((Element) attrsStrictCheckElement,
				builder.getBeanDefinition());
			builder.addPropertyValue(PARAM_TYPES_PROP_NAME, list);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element)
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected Class getBeanClass(Element element) {
		return InvokerData.class;
	}

}

