package info.bukova.isspst.signapi;

import org.springframework.beans.factory.annotation.Autowired;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayOutputStream;

/**
 * @author Pepa Rokos
 */
public class JnlpGeneratorImpl implements JnlpGenerator {

	@Autowired
	private HttpServletRequest request;

	@Override
	public byte[] generate() {
		String sessionId;

		if (request.getParameter("id") != null && !request.getParameter("id").isEmpty()) {
			sessionId = request.getParameter("id");
		} else {
			sessionId = request.getSession().getId();
		}

		try {
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

			Document document = docBuilder.newDocument();
			Element root = document.createElement("jnlp");
			root.setAttribute("spec", "1.0+");

			String signerUrl = request.getRequestURL().toString();
			signerUrl = signerUrl.substring(0, signerUrl.indexOf(request.getServletPath())) + "/api/sign";

			root.setAttribute("codebase", signerUrl);
			root.setAttribute("href", "signer.jnlp" + "?id=" + sessionId);
			document.appendChild(root);

			Element info = document.createElement("information");
			Element title = document.createElement("title");
			title.appendChild(document.createTextNode("Signer component"));
			info.appendChild(title);
			Element vendor = document.createElement("vendor");
			vendor.appendChild(document.createTextNode("bukova.info"));
			info.appendChild(vendor);
			root.appendChild(info);

			Element security = document.createElement("security");
			security.appendChild(document.createElement("all-permissions"));
			root.appendChild(security);

			Element resources = document.createElement("resources");
			resources.setAttribute("os", "Linux");
			Element j2se = document.createElement("j2se");
			j2se.setAttribute("version", "1.8+");
			Element jar = document.createElement("jar");
			jar.setAttribute("href", "pdfsigner.jar");
			resources.appendChild(j2se);
			resources.appendChild(jar);
			root.appendChild(resources);

			Element resourcesWin = document.createElement("resources");
			resourcesWin.setAttribute("os", "Windows");
			Element j2seWin = document.createElement("j2se");
			j2seWin.setAttribute("version", "1.8+");
			Element jarWin = document.createElement("jar");
			jarWin.setAttribute("href", "pdfsignerWin.jar");
			resourcesWin.appendChild(j2seWin);

			resourcesWin.appendChild(jarWin);
			root.appendChild(resourcesWin);

			Element appDesc = document.createElement("application-desc");
			appDesc.setAttribute("main-class", "info.bukova.pdfsigner.Main");
			Element argUrl = document.createElement("argument");
			argUrl.appendChild(document.createTextNode(signerUrl + "/data"));
			appDesc.appendChild(argUrl);
			Element argSession = document.createElement("argument");
			argSession.appendChild(document.createTextNode(sessionId));
			appDesc.appendChild(argSession);
			root.appendChild(appDesc);


			System.out.println(signerUrl);
			System.out.println(request.getSession().getId());

			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(document);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			StreamResult result = new StreamResult(bos);

			transformer.transform(source, result);

			return bos.toByteArray();

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		}

		return null;
	}

}
