package com.tandbergtv.watchpoint.pmm.action.asset.arrival;

import java.io.File;
import java.util.MissingResourceException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.exe.ExecutionContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import com.tandbergtv.watchpoint.pmm.util.TemplateProperties;

/**
 * Reads metadata fields that are configured in the templates-properties
 * and sets the value in the execution context.
 * 
 * @author Raj Prakash
 *
 */
public class ReadMetadata implements ActionHandler {

	private static final long serialVersionUID = 4049329988292513384L;
	
	private static final String FIELDS_PROP_PREFIX = "AssetArrival.MetadataToRead.";
	
	/* (non-Javadoc)
	 * @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext)
	 */
	public void execute(ExecutionContext context) throws Exception {
		String metadataFilePath = getStringValue(context, Variables.METADATA_FILE_PATH);
		Document metadataDocument = loadFile(metadataFilePath);

		int i=1;
		while(true) {
			String nameKey = FIELDS_PROP_PREFIX + i + ".name";
			String name;
			try {
				name = TemplateProperties.getString(nameKey);
			} catch(MissingResourceException e) {
				break;
			}
			name = name.trim();
			
			String xpathKey = FIELDS_PROP_PREFIX + i + ".xpath";
			String xpath = TemplateProperties.getString(xpathKey);
			xpath = xpath.trim();
			
			String fieldValue = getNodeValue(xpath, metadataDocument);
			context.setVariable(name, fieldValue);
			
			++i;
		}
	}

	/*
	 * Gets the String value of the variable (in case the data type is not string). Uses toString()
	 * for all data types.
	 */
	private String getStringValue(ExecutionContext context, String variableName) {
		Object value = context.getVariable(variableName);
		return (value != null) ? value.toString() : null;
	}
	
	/* Loads the xml file into a Document. */
	private Document loadFile(String filePath) throws Exception
	{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", Boolean.FALSE);			
		return factory.newDocumentBuilder().parse(new File(filePath)); 
	}
	
	/* Gets the node value from the given node for the given xpath expression. */
	private String getNodeValue(String expression, Node n) throws Exception
	{
		XPath xpath = XPathFactory.newInstance().newXPath();
		Node node = (Node) xpath.evaluate(expression, n, XPathConstants.NODE);
		return (node != null) ? node.getTextContent() : "";
	}

}
