package eu.stork.documentservice.utils;

import java.io.InputStream;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

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

//import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.GetDSSFileAction;

import eu.stork.documentservice.data.DatabaseConnectorMySQLImpl;
import eu.stork.documentservice.exceptions.DocumentServiceException;

public class XmlHelper {
	
	private static Properties props = new Properties();
	
	public static String getRequestId(String xmlRequest) throws DocumentServiceException
	{
		if (xmlRequest == null || xmlRequest.isEmpty())
			throw new DocumentServiceException("XML request is empty");
		else
		{
			try
			{
				InputStream is = Utils.getStream(xmlRequest, "UTF-8");
				DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance()
	                    .newDocumentBuilder();
				Document doc = dBuilder.parse(is);
				Element reqElement = doc.getDocumentElement();
				String reqId = reqElement.getAttribute("RequestID"); 
				return reqId.replace("_", "");
			}
			catch (Exception ex)
			{
				throw new DocumentServiceException("Unabled to parse xml.", ex);
			}
		}
	}
	
	public static String getRequestDocument(String xmlRequest) throws DocumentServiceException
	{
		if (xmlRequest == null || xmlRequest.isEmpty())
			throw new DocumentServiceException("XML request is empty");
		else
		{
			try
			{
				InputStream is = Utils.getStream(xmlRequest, "UTF-8");
				DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance()
	                    .newDocumentBuilder();
				Document doc = dBuilder.parse(is);
				String document = "";
				Element req = doc.getDocumentElement();
				NodeList nList0 = req.getChildNodes();
				for (int i = 0; i < nList0.getLength(); i++)
				{
					Node node = nList0.item(i);
					NodeList nList1 = node.getChildNodes();
					for (int j = 0; j < nList1.getLength(); j++)
					{
						NodeList nList2 = nList1.item(j).getChildNodes();
						for (int k = 0; k < nList2.getLength(); k++)
						{
							Node docNode =nList2.item(k);
							document = docNode.getTextContent();
						}
					}
				}
				return document;
			}
			catch (Exception ex)
			{
				throw new DocumentServiceException("Unabled to parse xml.", ex);
			}
		}
	}
	
	public static String getRequestDocumentData(String xmlRequest) throws DocumentServiceException
	{
		if (xmlRequest == null || xmlRequest.isEmpty())
			throw new DocumentServiceException("XML request is empty");
		else
		{
			try
			{
				InputStream is = Utils.getStream(xmlRequest, "UTF-8");
				DocumentBuilderFactory xmlFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder docBuilder = xmlFactory.newDocumentBuilder();
				Document xmlDoc = docBuilder.parse(is);
				XPathFactory xpathFact = XPathFactory.newInstance();
				XPath xpath = xpathFact.newXPath();
				return xpath.evaluate("/SignRequest/InputDocuments/Document/Base64Data/text()", xmlDoc);				
				
			}
			catch (Exception ex)
			{
				throw new DocumentServiceException("Unabled to parse xml.", ex);
			}
		}
	}
	
	public static String getRequestDocumentMime(String xmlRequest) throws DocumentServiceException
	{
		if (xmlRequest == null || xmlRequest.isEmpty())
			throw new DocumentServiceException("XML request is empty");
		else
		{
			try
			{
				InputStream is = Utils.getStream(xmlRequest, "UTF-8");
				DocumentBuilderFactory xmlFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder docBuilder = xmlFactory.newDocumentBuilder();
				Document xmlDoc = docBuilder.parse(is);
				XPathFactory xpathFact = XPathFactory.newInstance();
				XPath xpath = xpathFact.newXPath();
				return xpath.evaluate("/SignRequest/InputDocuments/Document/Base64Data/@MimeType", xmlDoc);				
				
			}
			catch (Exception ex)
			{
				throw new DocumentServiceException("Unabled to parse xml.", ex);
			}
		}
	}
	
	private static String getDocId(String response) throws DocumentServiceException
	{
		if (response == null || response.isEmpty())
			throw new DocumentServiceException("Response is empty");
		else
		{
			if (response.contains("docId"))
			{
				int index = response.indexOf("docId");
				String docText = response.substring(response.indexOf(">" ,index), response.indexOf("<", index));
				String docId = docText.replaceAll("[<>]", "");	//s:label name="docId" value="%{docId}"/			
				docId = docId.substring(docId.indexOf("/")+1);
				docId = docId.substring(docId.indexOf('/')+1);
				return docId.replace("/", "");
			}
			else
				throw new DocumentServiceException("No document ID in response.");
		}
	}
	
	/**
	 * String the document id
	 * @param docId the document id to strip
	 * @return the stripped ID
	 * @throws DocumentServiceException
	 */
	public static String StripDocId(String docId) throws DocumentServiceException
	{
		if (docId == null || docId.isEmpty())
			throw new DocumentServiceException("Doc ID is empty");
		else
		{
			docId = docId.substring(docId.indexOf("/")+1);
			docId = docId.substring(docId.indexOf('/')+1);
			return docId.replace("/", "");
		}
	}
	
	public static String verifyRequest(String transferRequest) throws DocumentServiceException
	{
		if (transferRequest == null || transferRequest.isEmpty())
			throw new DocumentServiceException("Transfer request is empty");
		else
		{			
			try {		
				String docId="";
				try{
				
//				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));	
//				System.out.println("url:"+props.getProperty("peps.url"));
				
//				final byte[] samlToken =  PEPSUtil.decodeSAMLTokenUrlSafe(parameters
//						.get(PEPSParameters.SAML_REQUEST.toString()));			
//			
//					final STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
//				      
//					final STORKAttrQueryRequest attrData= engine.validateSTORKAttrQueryRequest(samlToken);
					
//				String response = Utils.sendPost(props.getProperty("peps.url"), "SAMLRequest=" + transferRequest);
//				docId=getDocId(response);;
				docId = GetDSSFileAction.processDocRequest(transferRequest);
				}catch(Exception e){e.printStackTrace();}
				return docId;
				//FIXME
//				String response = Utils.sendPost(props.getProperty("peps.url"), "SAMLRequest=" + transferRequest);
//				return getDocId(response);
			} catch (Exception e) {
				e.printStackTrace();
				throw new DocumentServiceException("Could verify request.", e);
			} 
		}
	}
	
	public static String verifyRequestByte(byte[] transferRequest) throws DocumentServiceException
	{
		if (transferRequest == null)
			throw new DocumentServiceException("Transfer request is empty");
		else
		{			
			try {				
				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
				String response = Utils.sendPost(props.getProperty("peps.url"),"SAMLRequest=" + Utils.encodeBase64bytes(transferRequest, true));
				return getDocId(response);
			} catch (Exception e) {
				e.printStackTrace();
				throw new DocumentServiceException("Could not read properties.", e);
			}
	
		}
	}
}