package eu.dnetlib.enabling.aas.utils;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

import eu.dnetlib.enabling.aas.rmi.AuthenticateRequest;
import eu.dnetlib.enabling.aas.rmi.TypedString;
import eu.dnetlib.enabling.aas.service.A2Exception;


/**
 * Resource utility class.
 * 
 * @author mhorst
 * 
 */
public class ResourceUtils {
	
	protected static final Logger log = Logger.getLogger(ResourceUtils.class);
	
	/**
	 * Finds resourceId within AuthenticateRequest principals.
	 * TODO try to support more than one principal
	 * @param authenticateRequest
	 * @return resourceId principal
	 * @throws A2Exception
	 */
	public static TypedString findResourceIdPrincipal(AuthenticateRequest authenticateRequest) throws A2Exception {
		if (authenticateRequest==null || authenticateRequest.getPrincipals() == null
				|| authenticateRequest.getPrincipals().length == 0)
			return null;
		if (authenticateRequest.getPrincipals().length > 1) {
			throw new A2Exception("More than one principal found in AuthenticateRequest! " +
					"Currently only one principal is supported!");
		} else
			return authenticateRequest.getPrincipals()[0];
	}

	
	/**
	 * Converts xml RESOURCE_IDENTIFIER element with value attribute containing profId to simple profId string.
	 * @param sourceXmlProfId
	 * @return profId
	 */
	public static String convertProfId(String sourceXmlProfId) {
		if (sourceXmlProfId==null || sourceXmlProfId.length()==0)
			return null;
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        factory.setIgnoringComments(true);
	        DocumentBuilder db = null;
	        factory.setNamespaceAware(true);
	        factory.setValidating(false);
        	db = factory.newDocumentBuilder();
        	Document doc = db.parse(new InputSource(new StringReader(sourceXmlProfId)));
        	if (doc.getDocumentElement().hasAttribute("value"))
        		return doc.getDocumentElement().getAttribute("value");
        	else
        		return null;
        } catch (Exception e) {
        	log.error("Exception occured when converting profId sourceXmlProfId: "+sourceXmlProfId,e);
        	return null;
        }
	}
	
	/**
	 * Converts XML DOM representation to String.
	 * Output String is without xml header.
	 * @param doc
	 * @return xml String representation
	 */
	public static String convertDocumentToString(Document doc) {
		if (doc==null)
			return null;
		try {
			DOMSource domSource = new DOMSource(doc);
			StringWriter writer = new StringWriter();
			StreamResult result = new StreamResult(writer);
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
			transformer.transform(domSource, result);
			return writer.toString();
		} catch (TransformerException e) {
			log.error("Exception occured when converting document to String representation. Doc: "+doc,e);
			return null;
		}
	}
	
}
