/**
 *                                                                            
 *  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<String>();
	
	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 void loadBPMN(String fileURL) {
		clearBPMN();
		if (fileURL == null) {
			log.debug("fileURL was null");
			return;
		}
		// read from url
		InputStream in = null;
		try {
			URL url = new URL(fileURL);
			in = url.openStream();
		} catch (MalformedURLException e1) {
			log.error(e1.getLocalizedMessage());
			return;
		} catch (IOException e2) {
			log.error(e2.getLocalizedMessage());
			return;
		}
		readXML(in);
		try {
			in.close();
		} catch (IOException e) {
			log.error(e.getLocalizedMessage());
		}
	}
	
	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);
	}

}
