/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
 package org.eclipse.osbp.utils.vaadin.bpmn;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.osbp.utils.vaadin.bpmn.BpmnNode.BpmnShape;
import org.slf4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class BpmnConverter {

	private static Logger log = org.slf4j.LoggerFactory.getLogger(BpmnConverter.class);

	private final String XMLNS_PREFIX = "xmlns:";
	private final String BPMN_DIAGRAM = "bpmndi:BPMNDiagram";
	private final String BPMN_PROCESS = "process";
	private final String BPMN_SEQ_FLOW = "sequenceFlow";
	private final String BPMN_START_EVENT = "startEvent";
	private final String BPMN_MESSAGE_START_EVENT_DEF = "messageEventDefinition";
	private final String BPMN_ERROR_END_EVENT_DEF = "errorEventDefinition";
	private final String BPMN_END_EVENT = "endEvent";
	private final String BPMN_TASK = "task";
	private final String BPMN_USER_TASK = "userTask";
	private final String BPMN_SCRIPT_TASK = "scriptTask";
	private final String BPMN_SERVICE_TASK = "serviceTask";
	private final String BPMN_RECEIVE_TASK = "receiveTask";
	private final String BPMN_SEND_TASK = "sendTask";
	private final String BPMN_PARALLEL_GATEWAY = "parallelGateway";
	private final String BPMN_EXCLUSIVE_GATEWAY = "exclusiveGateway";
	private final String BPMN_INCLUSIVE_GATEWAY = "inclusiveGateway";
	private final String BPMN_CALL_ACTIVITY = "callActivity";

	private Map<String, BpmnNode> bpmnComponents = new HashMap<>();
	private Map<String, BpmnNode> bpmnSeqFlowComponents = new HashMap<>();
	private List<String> nsTagNamePrefixes = new ArrayList<>();
	
	private String tagNamePrefix = "";

	private StringBuilder bpmnJsCreationCode = new StringBuilder();

	private NodeList emptyNodeList = new NodeList() {
		
		@Override
		public Node item(int index) {
			return null;
		}
		
		@Override
		public int getLength() {
			return 0;
		}
	};

	public String getTagName(String tagName) {
		return tagNamePrefix + ":" + tagName;
	}

	public void setTagNamePrefix(String tagNamePrefix) {
		this.tagNamePrefix = tagNamePrefix;
	}

	public String getBpmnJsCreationCode() {
		return bpmnJsCreationCode.toString();
	}

	public void clearBPMN() {
		bpmnComponents.clear();
		bpmnSeqFlowComponents.clear();
		nsTagNamePrefixes.clear();
	}
	
	public boolean loadBPMN(String fileURL) {
		clearBPMN();
		if (fileURL == null) {
			log.error("loadBPMN: unable to load BPM definition - fileURL is 'null'");
			return false;
		}
		// read from url
		InputStream in = null;
		try {
			URL url = new URL(fileURL);
			in = url.openStream();
		} catch (MalformedURLException e1) {
			log.error(e1.getLocalizedMessage());
			return false;
		} catch (IOException e2) {
			log.error(e2.getLocalizedMessage());
			return false;
		}
		readXML(in);
		try {
			in.close();
		} catch (IOException e) {
			log.error(e.getLocalizedMessage());
		}
		return true;
	}
	
	public void readXML(InputStream inputStream) {
		try {

			DocumentBuilderFactory dbFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(inputStream);

			// optional, but recommended
			// read this -
			// http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
			doc.getDocumentElement().normalize();

			log.debug("Root element :"
					+ doc.getDocumentElement().getNodeName());
			fillNsTagNamePrefixes(doc);
			log.debug("----------------------------");

			NodeList nBpmnProcessList = getElementsByTagNameIntern(doc, BPMN_PROCESS);
			log.debug("----------------------------");
			readBpmnProcessNodeList(doc, nBpmnProcessList);
			if (bpmnComponents.isEmpty()){
				readDiagramNodes(doc);
			}
			printOutBpmnComponents();
			fillCreatedBpmnComponentJsStatements();
			fillCreatedSeqFlowBpmnComponentJsStatements();
		} catch (Exception e) {
			log.error("{}", e);
		}
	}

	private void fillNsTagNamePrefixes(Document doc){
		NamedNodeMap namedNodeMap = doc.getDocumentElement().getAttributes();
		for (int i = 0; i < namedNodeMap.getLength(); i++) {
			Node nNode = namedNodeMap.item(i);
			String nNodeName = nNode.getNodeName();
			if (nNodeName != null && nNodeName.startsWith(XMLNS_PREFIX)){
				log.debug("namedNode: {}", nNodeName);
				String prefix = nNodeName.substring(XMLNS_PREFIX.length(), nNodeName.length());
				log.debug("nsPrefix: {}", prefix);
				nsTagNamePrefixes.add(nNodeName.substring(XMLNS_PREFIX.length(), nNodeName.length()));
			}
		}
	}
	
	private NodeList getElementsByTagNameIntern(Document doc, String tagName){
		for (String nsTagNamePrefix : nsTagNamePrefixes) {
			NodeList nodeList = doc.getElementsByTagName(nsTagNamePrefix + ":" + tagName);
			if (nodeList.getLength() > 0){
				setTagNamePrefix(nsTagNamePrefix);
				return nodeList;
			}
		} 
		return emptyNodeList;
	}
	
	private void printOutBpmnComponents() {
		log.debug("*************** BpmnComponent-Map *******************");
		for (BpmnNode bpmnComponent : bpmnComponents.values()) {
			String shape = (bpmnComponent.getShape() != null ? bpmnComponent.getShape().name() : "");
			log.debug("\nID: " + bpmnComponent.getId());
			log.debug("\nName: " + bpmnComponent.getName());
			log.debug("\nX: " + bpmnComponent.getX());
			log.debug("\nY: " + bpmnComponent.getY());
			log.debug("\nWidth: " + bpmnComponent.getWidth());
			log.debug("\nHeight: " + bpmnComponent.getHeight());
			log.debug("\nTarget: " + bpmnComponent.getTarget());
			log.debug("\nShape: {}", shape);
			log.debug("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
		}
		log.debug("*****************************************************");
	}

	private void fillCreatedBpmnComponentJsStatements() {
		bpmnJsCreationCode.setLength(0);
		log.debug("//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CreateBpmnComponentJsStatements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		String out;
		for (BpmnNode bpmnComponent : bpmnComponents.values()) {
			BpmnShape bpmnShape = bpmnComponent.getShape();
			if (bpmnShape != null) {
				switch (bpmnShape) {
				case STARTEVENT:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateStart");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case MESSAGE_STARTEVENT:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateMessageStart");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case ENDEVENT:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateEnd");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case ERROR_ENDEVENT:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateErrorEnd");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case TASK:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateTask");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case USERTASK:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateUserTask");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case SCRIPTTASK:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateScriptTask");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case SERVICETASK:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateServiceTask");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case RECEIVETASK:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateReceiveTask");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case SENDTASK:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateSendTask");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case PARALLEL_GATEWAY:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateParallelCondition");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case EXCLUSIVE_GATEWAY:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateExclusiveCondition");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case INCLUSIVE_GATEWAY:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateInclusiveCondition");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				case CALL_ACTIVITY:
					out = getCreateJsVarAsString(bpmnComponent, "bpmnCreateCallActivity");
					bpmnJsCreationCode.append(out);
					log.debug(out);
					break;
				default:
					log.error("Shape not found {}", bpmnShape.name());
					break;
				}
			}
		}
		log.debug("//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
	}

	private void fillCreatedSeqFlowBpmnComponentJsStatements() {
		log.debug("//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CreateSeqFlowBpmnComponentJsStatements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		String out;
		for (BpmnNode bpmnComponent : bpmnSeqFlowComponents.values()) {
			BpmnShape bpmnShape = bpmnComponent.getShape();
			if (bpmnShape != null && bpmnShape == BpmnShape.SEQ_FLOW) {
				out = "\ninsertEdge(graph, parent, '" + bpmnComponent.getId() + "', '" + bpmnComponent.getName() + "', "
						+ bpmnComponent.getSource().toLowerCase().replace("-", "_") + ", "
						+ bpmnComponent.getTarget().toLowerCase().replace("-", "_") + ");";
				bpmnJsCreationCode.append(out);
				log.debug(out);
			}
		}
		log.debug("//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
	}
	
	private String getCreateJsVarAsString(BpmnNode bpmnComponent, String methodName) {
		return "\nvar "
				+ bpmnComponent.getId().toLowerCase().replace("-", "_")
				+ " = " + methodName + "(graph, parent, '"
				+ bpmnComponent.getId() + "', '"
				+ bpmnComponent.getName() + "', "
				+ bpmnComponent.getX() + ", "
				+ bpmnComponent.getY() + ", "
				+ bpmnComponent.getWidth() + ", "
				+ bpmnComponent.getHeight() + ");";
	}

	private void readBpmnDiagramNodeList(NodeList nList) {

		for (int temp = 0; temp < nList.getLength(); temp++) {

			Node nNode = nList.item(temp);

			if (nNode.getNodeType() == Node.ELEMENT_NODE) {
				String nNodeName = nNode.getNodeName();
				if (!"bpmndi:BPMNEdge".equals(nNodeName)) {
					log.debug("\n===============================");
					log.debug("\nCurrent Element :" + nNodeName);
					log.debug("\n===============================");

					Element eElement = (Element) nNode;

					if ("dc:Bounds".equals(nNodeName)) {
						Element parentElement = (Element) eElement
								.getParentNode();
						String bpmnElementKey = parentElement
								.getAttribute("bpmnElement");
						if (!bpmnElementKey.isEmpty()
								&& bpmnComponents.containsKey(bpmnElementKey)) {

							BpmnNode bpmnComponent = bpmnComponents
									.get(bpmnElementKey);

							log.debug(nNodeName + " bpmnElement : "
									+ bpmnElementKey);
							bpmnComponent.setX(new Float(eElement
									.getAttribute("x")).intValue());
							bpmnComponent.setY(new Float(eElement
									.getAttribute("y")).intValue());
							bpmnComponent.setWidth(new Float(eElement
									.getAttribute("width")).intValue());
							bpmnComponent.setHeight(new Float(eElement
									.getAttribute("height")).intValue());
							log.debug(nNodeName + " x : "
									+ bpmnComponent.getX());
							log.debug(nNodeName + " y : "
									+ bpmnComponent.getY());
							log.debug(nNodeName + " width : "
									+ bpmnComponent.getWidth());
							log.debug(nNodeName + " height : "
									+ bpmnComponent.getHeight());
						}
					} else {
						log.debug(nNodeName + " id : "
								+ eElement.getAttribute("id"));
					}
					readBpmnDiagramNodeList(eElement.getChildNodes());
				}
			}
		}
	}

	private void readBpmnProcessNodeList(Document doc, NodeList nList) {

		for (int temp = 0; temp < nList.getLength(); temp++) {

			Node nNode = nList.item(temp);

			if (nNode.getNodeType() == Node.ELEMENT_NODE) {
				String nNodeName = nNode.getNodeName();
				log.debug("\nProcess: " + nNodeName);
				log.debug("\n####################################");
				if (getTagName(BPMN_PROCESS).equals(nNodeName)) {
					Element eElement = (Element) nNode;
					readBpmnProcessNodeList(doc, eElement.getChildNodes());
					readDiagramNodes(doc);
				} else {
					if (getTagName(BPMN_START_EVENT).equals(nNodeName)) {
						if (((Element) nNode).getElementsByTagName(getTagName(BPMN_MESSAGE_START_EVENT_DEF)).getLength()>0){
							createMessageStartEvent(nNode);
						} else {
							createStartEvent(nNode);
						}
					} else if ((getTagName(BPMN_TASK).equals(nNodeName))) {
						createTask(nNode);
					} else if ((getTagName(BPMN_USER_TASK).equals(nNodeName))) {
						createUserTask(nNode);
					} else if ((getTagName(BPMN_SCRIPT_TASK).equals(nNodeName))) {
						createScriptTask(nNode);
					} else if ((getTagName(BPMN_SERVICE_TASK).equals(nNodeName))) {
						createServiceTask(nNode);
					} else if ((getTagName(BPMN_RECEIVE_TASK).equals(nNodeName))) {
						createReceiveTask(nNode);
					} else if ((getTagName(BPMN_SEND_TASK).equals(nNodeName))) {
						createSendTask(nNode);
					} else if ((getTagName(BPMN_PARALLEL_GATEWAY).equals(nNodeName))) {
						createParallelGateway(nNode);
					} else if ((getTagName(BPMN_EXCLUSIVE_GATEWAY).equals(nNodeName))) {
						createExclusiveGateway(nNode);
					} else if ((getTagName(BPMN_INCLUSIVE_GATEWAY).equals(nNodeName))) {
						createInclusiveGateway(nNode);
					} else if ((getTagName(BPMN_CALL_ACTIVITY).equals(nNodeName))) {
						createCallActivity(nNode);
					} else if ((getTagName(BPMN_END_EVENT).equals(nNodeName))) {
						if (((Element) nNode).getElementsByTagName(getTagName(BPMN_ERROR_END_EVENT_DEF)).getLength()>0){
							createErrorEndEvent(nNode);
						} else {
							createEndEvent(nNode);
						}
					} else if ((getTagName(BPMN_SEQ_FLOW).equals(nNodeName))) {
						createSeqFlow(nNode);
					}
				}
			}
		}

	}

	private void readDiagramNodes(Document doc) {
		NodeList nBpmnDiagramList = doc
				.getElementsByTagName(BPMN_DIAGRAM);
		readBpmnDiagramNodeList(nBpmnDiagramList);
	}

	private BpmnNode getBpmnComponent(Node nNode) {
		String nNodeName = nNode.getNodeName();
		log.debug("\n===============================");
		log.debug("\nCurrent Element :" + nNodeName);
		log.debug("\n===============================");

		Element eElement = (Element) nNode;
		String id = eElement.getAttribute("id");
		BpmnNode bpmnComponent;
		if (bpmnComponents.containsKey(id)) {
			bpmnComponent = bpmnComponents.get(id);
		} else {
			bpmnComponent = new BpmnNode();
			bpmnComponent.setId(id);
		}
		if (getTagName(BPMN_SEQ_FLOW).equals(nNodeName)) {
			bpmnComponent.setSource(eElement.getAttribute("sourceRef"));
			bpmnComponent.setTarget(eElement.getAttribute("targetRef"));
		}
		bpmnComponent.setName(eElement.getAttribute("name"));
		log.debug(nNodeName + " id : " + bpmnComponent.getId());
		log.debug(nNodeName + " name : " + bpmnComponent.getName());

		return bpmnComponent;
	}

	private void createTask(Node nNode) {
		BpmnNode task = getBpmnComponent(nNode);
		task.setShape(BpmnShape.TASK);
		bpmnComponents.put(task.getId(), task);
	}

	private void createUserTask(Node nNode) {
		BpmnNode userTask = getBpmnComponent(nNode);
		userTask.setShape(BpmnShape.USERTASK);
		bpmnComponents.put(userTask.getId(), userTask);
	}
	
	private void createScriptTask(Node nNode) {
		BpmnNode userTask = getBpmnComponent(nNode);
		userTask.setShape(BpmnShape.SCRIPTTASK);
		bpmnComponents.put(userTask.getId(), userTask);
	}
	
	private void createServiceTask(Node nNode) {
		BpmnNode serviceTask = getBpmnComponent(nNode);
		serviceTask.setShape(BpmnShape.SERVICETASK);
		bpmnComponents.put(serviceTask.getId(), serviceTask);
	}
	
	private void createReceiveTask(Node nNode) {
		BpmnNode userTask = getBpmnComponent(nNode);
		userTask.setShape(BpmnShape.RECEIVETASK);
		bpmnComponents.put(userTask.getId(), userTask);
	}
	
	private void createSendTask(Node nNode) {
		BpmnNode userTask = getBpmnComponent(nNode);
		userTask.setShape(BpmnShape.SENDTASK);
		bpmnComponents.put(userTask.getId(), userTask);
	}
	
	private void createStartEvent(Node nNode) {
		BpmnNode startEvent = getBpmnComponent(nNode);
		startEvent.setShape(BpmnShape.STARTEVENT);
		bpmnComponents.put(startEvent.getId(), startEvent);
	}

	private void createMessageStartEvent(Node nNode) {
		BpmnNode startEvent = getBpmnComponent(nNode);
		startEvent.setShape(BpmnShape.MESSAGE_STARTEVENT);
		bpmnComponents.put(startEvent.getId(), startEvent);
	}
	
	private void createErrorEndEvent(Node nNode) {
		BpmnNode endEvent = getBpmnComponent(nNode);
		endEvent.setShape(BpmnShape.ERROR_ENDEVENT);
		bpmnComponents.put(endEvent.getId(), endEvent);
	}

	private void createEndEvent(Node nNode) {
		BpmnNode endEvent = getBpmnComponent(nNode);
		endEvent.setShape(BpmnShape.ENDEVENT);
		bpmnComponents.put(endEvent.getId(), endEvent);
	}
	
	private void createParallelGateway(Node nNode) {
		BpmnNode createParallelGateway = getBpmnComponent(nNode);
		createParallelGateway.setShape(BpmnShape.PARALLEL_GATEWAY);
		bpmnComponents.put(createParallelGateway.getId(), createParallelGateway);
	}

	private void createExclusiveGateway(Node nNode) {
		BpmnNode createExclusiveGateway = getBpmnComponent(nNode);
		createExclusiveGateway.setShape(BpmnShape.EXCLUSIVE_GATEWAY);
		bpmnComponents.put(createExclusiveGateway.getId(), createExclusiveGateway);
	}
	
	private void createInclusiveGateway(Node nNode) {
		BpmnNode createExclusiveGateway = getBpmnComponent(nNode);
		createExclusiveGateway.setShape(BpmnShape.INCLUSIVE_GATEWAY);
		bpmnComponents.put(createExclusiveGateway.getId(), createExclusiveGateway);
	}
	
	private void createCallActivity(Node nNode) {
		BpmnNode createCallActivity = getBpmnComponent(nNode);
		createCallActivity.setShape(BpmnShape.CALL_ACTIVITY);
		bpmnComponents.put(createCallActivity.getId(), createCallActivity);
	}
	
	private void createSeqFlow(Node nNode) {
		BpmnNode createSeqFlow = getBpmnComponent(nNode);
		createSeqFlow.setShape(BpmnShape.SEQ_FLOW);
		bpmnSeqFlowComponents.put(createSeqFlow.getId(), createSeqFlow);
	}

}
