package com.agilex.vamf.missionhealth.testutility;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.agilex.vamf.utils.NamespaceContextManager;

/**
 * 
 * @author j.ray
 */
public class XpathHelper {

	public static Object get(Node source, String xpathStatement,
			QName returnType) {
		Object result = null;
		try {

			XPath xpath = XPathFactory.newInstance().newXPath();
			NamespaceContext nsContext = new NamespaceContextManager();
			xpath.setNamespaceContext(nsContext);
			XPathExpression expr = xpath.compile(xpathStatement);
			if (returnType == null) {
				result = expr.evaluate(source);
			} else {
				result = expr.evaluate(source, returnType);
			}
		} catch (XPathExpressionException ex) {
			Logger.getLogger(XpathHelper.class.getName()).log(Level.SEVERE,
					null, ex);
			throw new RuntimeException(ex);
		}
		return result;
	}

	public static Node getNode(Document sourceDocument, String xpathStatement) {
		return (Node) get(sourceDocument, xpathStatement, XPathConstants.NODE);
	}

	public static Node getNode(Node sourceNode, String xpathStatement) {
		return (Node) get(sourceNode, xpathStatement, XPathConstants.NODE);
	}

	public static NodeList getNodeList(Document sourceDocument,
			String xpathStatement) {
		return (NodeList) get(sourceDocument, xpathStatement,
				XPathConstants.NODESET);
	}

	public static NodeList getNodeList(Node sourceNode, String xpathStatement) {
		return (NodeList) get(sourceNode, xpathStatement,
				XPathConstants.NODESET);
	}

	public static String getString(Node sourceNode, String xpathStatement) {
		return (String) get(sourceNode, xpathStatement, XPathConstants.STRING);
	}

	public static int getInt(Node sourceNode, String xpathStatement) {
		return getDouble(sourceNode, xpathStatement).intValue();
	}

	public static Long getLong(Node sourceNode, String xpathStatement) {
		return getDouble(sourceNode, xpathStatement).longValue();
	}

	public static Double getDouble(Node sourceNode, String xpathStatement) {
		return (Double) get(sourceNode, xpathStatement, XPathConstants.NUMBER);
	}

	public static URI getUri(Node sourceNode, String xpathStatement) {
		String s = getString(sourceNode, xpathStatement);
		URI u;
		try {
			u = new URI(s);
		} catch (URISyntaxException e) {
			throw new RuntimeException(e);
		}
		return u;
	}
}
