/*****************************************************************************
 * Copyright (c) 2020 CEA LIST.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *  Ansgar Radermacher  ansgar.radermacher@cea.fr
 *
 *****************************************************************************/

package org.eclipse.papyrus.robotics.ros2.reverse.fromsys;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.papyrus.designer.infra.base.StringUtils;
import org.eclipse.papyrus.designer.languages.cpp.library.CppUriConstants;
import org.eclipse.papyrus.designer.transformation.base.utils.ModelManagement;
import org.eclipse.papyrus.designer.uml.tools.utils.ElementUtils;
import org.eclipse.papyrus.infra.core.resource.BadArgumentExcetion;
import org.eclipse.papyrus.infra.core.resource.NotFoundException;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationModel;
import org.eclipse.papyrus.robotics.core.utils.FileExtensions;
import org.eclipse.papyrus.robotics.core.utils.ParameterUtils;
import org.eclipse.papyrus.robotics.core.utils.ScanUtils;
import org.eclipse.papyrus.robotics.profile.robotics.components.ComponentDefinitionModel;
import org.eclipse.papyrus.robotics.profile.robotics.components.ComponentInstance;
import org.eclipse.papyrus.robotics.profile.robotics.generics.Connects;
import org.eclipse.papyrus.robotics.profile.robotics.parameters.ParameterEntry;
import org.eclipse.papyrus.robotics.ros2.base.ProcessUtils;
import org.eclipse.papyrus.robotics.ros2.base.Ros2Constants;
import org.eclipse.papyrus.robotics.ros2.base.Ros2ProcessBuilder;
import org.eclipse.papyrus.robotics.ros2.reverse.PortInfo;
import org.eclipse.papyrus.robotics.ros2.reverse.PortInfo.PortKind;
import org.eclipse.papyrus.robotics.ros2.reverse.ReverseConstants;
import org.eclipse.papyrus.robotics.ros2.reverse.fromsys.MessageParser.MessageEntry;
import org.eclipse.papyrus.robotics.ros2.reverse.utils.CreatePortUtils;
import org.eclipse.papyrus.robotics.ros2.reverse.utils.FolderUtils;
import org.eclipse.papyrus.robotics.ros2.reverse.utils.ModelTemplate;
import org.eclipse.papyrus.robotics.ros2.reverse.utils.ReverseUtils;
import org.eclipse.papyrus.robotics.ros2.reverse.utils.ServiceDefUtils;
import org.eclipse.papyrus.uml.diagram.wizards.Activator;
import org.eclipse.papyrus.uml.tools.utils.PackageUtil;
import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil;
import org.eclipse.swt.widgets.Display;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.ConnectorEnd;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLPackage;

/**
 * Reverse existing ROS2 nodes. The reversal is based on the ROS2 command line tool:
 * 1. The set of nodes is obtained using "ros2 node list"
 * 2. The information about the ports of each node is obtained using "ros2 node info <nodename>""
 */
@SuppressWarnings("nls")
public class ReverseNodes {

	protected IProgressMonitor monitor;

	protected List<URI> pathMapURIs;

	protected List<NodeInfo> niList;

	protected Map<String, List<NodeInfo>> portHash;

	protected int response;

	protected static int DIALOG_NO = 0;
	protected static int DIALOG_YES = 1;
	protected static int DIALOG_NO_ALL = 2;
	protected static int DIALOG_YES_ALL = 3;

	protected class UIQuestion implements Runnable {

		UIQuestion(String fileName) {
			this.fileName = fileName;
		}

		protected String fileName;

		@Override
		public void run() {
			response = MessageDialog.open(MessageDialog.QUESTION, Display.getDefault().getActiveShell(),
					"Overwrite model?",
					String.format(
							"A model for the node exists already (at the default location \"%s\"). Should it (and eventually subsequent existing ones) be overwritten?", fileName),
					MessageDialog.DIALOG_DEFAULT_BOUNDS, "no", "yes", "no to all", "yes to all");
		}
	};

	public ReverseNodes(IProgressMonitor monitor) {
		this.monitor = monitor;
		for (Resource resource : ModelManagement.getResourceSet().getResources()) {
			resource.unload();
		}
		ModelManagement.getResourceSet().getResources().clear();
		pathMapURIs = ScanUtils.allPathmapModels(FileExtensions.SERVICEDEF_UML);
		niList = new ArrayList<NodeInfo>();
		portHash = new HashMap<String, List<NodeInfo>>();
		response = DIALOG_YES;
	}

	/**
	 * read the list of nodes and create models.
	 */
	public void readNodeList() {
		Ros2ProcessBuilder pb = new Ros2ProcessBuilder(Ros2Constants.NODE, Ros2Constants.LIST);
		try {
			Process p = pb.start();
			BufferedReader results = new BufferedReader(new InputStreamReader(p.getInputStream()));
			boolean error = ProcessUtils.logErrors(p);
			if (error) {
				return;
			}

			// first, read all lines into an array in order to calculate
			// the number of nodes
			String line1;
			List<String> lines = new ArrayList<String>();
			while ((line1 = results.readLine()) != null) {
				String frags[] = line1.split(MessageParser.SLASH);
				if (frags.length >= 2) {
					String name = frags[1].trim();
					if (name.endsWith("_rclcpp_node") || name.endsWith("_client_node") ||
							name.startsWith("transform_listener_") || name.startsWith("launch_ros_")) {
						// skip
					} else {
						lines.add(line1);
					}
				}
			}
			results.close();

			monitor.beginTask("reverse nodes", lines.size() + 1);
			for (String line : lines) {
				reverseNode(line);
				monitor.worked(1);
				if (monitor.isCanceled())
					break;
			}
			createSystem();
		} catch (IOException | CoreException exp) {
			Activator.log.error(exp);
		}
	}

	public void reverseNode(String line) {
		String frags[] = line.split(MessageParser.SLASH);
		try {
			// TODO: always right? (possible that size > 3?)
			int top = (frags.length == 3) ? 1 : 0;

			String pkgName = frags[top].trim();
			final String name = frags[top+1].trim();

			monitor.subTask("reverse component " + name);
			String fileName = name + FileExtensions.COMPDEF_UML;
			// pass complete filename (a bit abusing the extension attribute)
			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
			if (pkgName.length() == 0) {
				IProject project = FolderUtils.obtainProject(fileName);
				if (project != null) {
					pkgName = project.getName();
				} else {
					// could not determine
					pkgName = name;
				}
			}

			IProject project = root.getProject(pkgName);
			IProgressMonitor progressMonitor = new NullProgressMonitor();
			if (!project.exists()) {
				project.create(progressMonitor);
			}
			if (!project.isOpen()) {
				project.open(progressMonitor);
			}

			NodeInfo ni = new NodeInfo();
			ni.name = name;
			IFolder fModels = FolderUtils.createFolderStructure(project);
			IFolder fComponents = FolderUtils.getComponentFolder(fModels);
			IFile fCompModel = fComponents.getFile(fileName);
			URI newURI = URI.createURI("platform:/resource/" + pkgName + "/models/components/" + fileName);

			// Does the model already exist? Only ask again, if user responded with YES or NO before
			// (not one of the "all options")
			if (fCompModel.exists() && (response == DIALOG_NO || response == DIALOG_YES)) {
				Display.getDefault().syncExec(new UIQuestion(fCompModel.toString()));
			}
			if (!fCompModel.exists() || response == DIALOG_YES || response == DIALOG_YES_ALL) {
				ModelTemplate mt = new ModelTemplate(newURI, "compdef");
				final NotationModel notation = mt.getNotationModel();

				final Package pkg = mt.getUMLModel();
				
				// load primitive types
				PackageUtil.loadPackage(URI.createURI(ReverseMessages.PATHMAP_ROS2_PRIMITIVE_UML), pkg.eResource().getResourceSet());
				PackageUtil.loadPackage(CppUriConstants.ANSIC_LIB_URI, pkg.eResource().getResourceSet());

				final String lineFinal = line;
				RecordingCommand reverseComponent = new RecordingCommand(mt.getDomain()) {
					@Override
					protected void doExecute() {
						// mark component as external (=> no code generation)
						ComponentDefinitionModel cd = StereotypeUtil.applyApp(pkg, ComponentDefinitionModel.class);
						cd.setExternal(true);

						pkg.setName(name);
						ReverseUtils.setXmlID(pkg);

						Class clazz = (Class) pkg.getOwnedType(ReverseConstants.MODEL_NAME_UC);
						ni.type = clazz;
						clazz.setName(name);
						ReverseUtils.setXmlID(clazz);
						reversePorts(clazz, ni, lineFinal, false);
						reverseParams(clazz, lineFinal);

						Diagram diagram;
						try {
							diagram = notation.getDiagram(ReverseConstants.MODEL_NAME_UC);
							final String newName = StringUtils.upperCaseFirst(name) + " diagram";
							diagram.setName(newName);
						} catch (NotFoundException | BadArgumentExcetion e) {
							e.printStackTrace();
						}
					}
				};
				mt.executeCmd(reverseComponent);
				mt.save(progressMonitor);
				mt.dispose();
			} else {
				// obtain clazz
				Resource r = ModelManagement.getResourceSet().getResource(newURI, true);
				Package rootPkg = (Package) r.getContents().get(0);
				// retrieve first class in Model
				NamedElement ne = rootPkg.getOwnedMember(null, false, UMLPackage.eINSTANCE.getClass_());
				if (ne instanceof Class) {
					ni.type = (Class) ne;
				} else {
					Activator.log.debug("not found");
				}
				// reverse ports without updating the component (in order to fill port hashMap)
				reversePorts(ni.type, ni, line, true);
			}
			niList.add(ni);
		} catch (CoreException | ServiceException e) {
			e.printStackTrace();
		}
	}

	public void createSystem() throws CoreException {
		String fileName = "fromRos.uml";
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IFile systemModel = root.getFile(new Path("/reverse/models/system/" + fileName));

		if (systemModel.exists()) {
			// ask again, unless previous response was not one of the "all" options
			if (response == DIALOG_NO || response == DIALOG_YES) {
				Display.getDefault().syncExec(new UIQuestion(systemModel.toString()));
			}
			if (!(response == DIALOG_YES || response == DIALOG_YES_ALL)) {
				return;
			}
		}

		String pkgName = "reverse";
		IProject project = root.getProject(pkgName);
		IProgressMonitor progressMonitor = new NullProgressMonitor();
		if (!project.exists()) {
			project.create(progressMonitor);
		}
		if (!project.isOpen()) {
			project.open(progressMonitor);
		}
		
		FolderUtils.createFolderStructure(project);
		URI newURI = URI.createURI("platform:/resource/reverse/models/system/" + fileName);
		try {
			ModelTemplate mt = new ModelTemplate(newURI, "system");
			RecordingCommand rc = new RecordingCommand(mt.getDomain()) {

				@Override
				protected void doExecute() {
					Package root = mt.getUMLModel();
					Diagram diagram;
					try {
						diagram = mt.getNotationModel().getDiagram(ReverseConstants.MODEL_NAME_UC);
						diagram.setName("System diagram");
					} catch (NotFoundException | BadArgumentExcetion e) {
						Activator.log.error(e);
						;
					}
					Class system = (Class) root.getOwnedMember("System");
					ReverseUtils.setXmlID(system);

					// create instances
					for (NodeInfo ni : niList) {
						if (system.getMember(ni.name) == null) {
							Property instance = system.createOwnedAttribute(ni.name, ni.type);
							ReverseUtils.setXmlID(instance);
							ComponentInstance ci = StereotypeUtil.applyApp(instance, ComponentInstance.class);
							ReverseUtils.setXmlID(ci, "ID_ST_" + ni.name);
						}
					}
					for (String portName : portHash.keySet()) {
						Connector c = system.createOwnedConnector(null);
						StereotypeUtil.applyApp(c, Connects.class);
						String cname = "";
						for (NodeInfo ni : portHash.get(portName)) {
							// ignore connections to visualization/simulation nodes
							if (!ni.name.equals("rviz") && !ni.name.equals("gazebo")) {
								ConnectorEnd end = c.createEnd();

								end.setPartWithPort(system.getAttribute(ni.name, null));
								if (ni.type != null) {
									end.setRole(ni.type.getOwnedPort(portName, null));
								}
								cname += "_" + ni.name;
							}
						}
						ReverseUtils.setXmlID(c, "ID_C" + cname);

						if (c.getEnds().size() < 2) {
							c.destroy();
						}
					}
				}
			};
			mt.executeCmd(rc);
			mt.save(monitor);
		} catch (ServiceException e) {
			Activator.log.error(e);
			;
		}

	}

	/**
	 * Reverse ports and add them to the passed component
	 * 
	 * @param component
	 *            the component
	 * @param ni
	 *            the node info
	 * @param qName
	 *            the qualified name of the component (passed to ros2 command line tool)
	 * @param readOnly
	 *            if true, only fill fill passed node info, don't update component
	 */
	public void reversePorts(Class component, NodeInfo ni, String qName, boolean readOnly) {
		Ros2ProcessBuilder pb = new Ros2ProcessBuilder(Ros2Constants.NODE, Ros2Constants.INFO, qName);
		try {
			Process p = pb.start();
			BufferedReader results = new BufferedReader(new InputStreamReader(p.getInputStream()));
			boolean error = ProcessUtils.logErrors(p);
			if (error) {
				return;
			}
			String line;
			PortKind currentPK = PortKind.PUBLISHER;
			while ((line = results.readLine()) != null) {
				line = MessageParser.filterComment(line);
				if (line.contains("Publishers:")) {
					currentPK = PortKind.PUBLISHER;
				} else if (line.contains("Subscribers:")) {
					currentPK = PortKind.SUBSCRIBER;
				} else if (line.contains("Service Servers:")) {
					currentPK = PortKind.SERVER;
				} else if (line.contains("Service Clients:")) {
					currentPK = PortKind.CLIENT;
				} else if (line.contains("Action Servers:")) {
					currentPK = PortKind.ACTION_SRV;
				} else if (line.contains("Action Clients:")) {
					currentPK = PortKind.ACTION_CLI;
				} else {
					String frags[] = line.split(MessageParser.COLON);
					if (frags.length == 2) {
						String qPortName = frags[0].trim();
						String qMessageName = frags[1].trim();
						MessageEntry entry = MessageParser.extractMessageEntry(qMessageName);
						if (entry.pkgName.equals("rcl_interfaces")
								|| entry.pkgName.equals("lifecycle_msgs")
								|| entry.pkgName.equals("rosgraph_msgs")) {
							// length 3, e.g. "/ROSadder/change_state: lifecycle_msgs/srv/ChangeState" indicate automatically
							// standard interfaces
							// TODO - might need info whether a lifecycle node.
							continue;
						}
						String portName = qPortName.trim().substring(1);
						List<NodeInfo> niWithName = portHash.get(portName);
						if (niWithName == null) {
							niWithName = new ArrayList<NodeInfo>();
						}
						niWithName.add(ni);
						portHash.put(portName, niWithName);
						Interface sd = ServiceDefUtils.getServiceDef(component, pathMapURIs, currentPK, entry);
						if (sd == null) {
							break;
						}
						PortInfo pi = new PortInfo();
						ni.ports.add(pi);
						pi.dtQName = portName;
						pi.pk = currentPK;
						pi.topic = portName;
						if (!readOnly) {
							CreatePortUtils.createPort(component, pi, sd);
						}
					}
				}
			}
			results.close();

		} catch (IOException exp) {
			Activator.log.error(exp);
		}
	}

	public void reverseParams(Class component, String qName) {
		Ros2ProcessBuilder pb = new Ros2ProcessBuilder(Ros2Constants.PARAM, Ros2Constants.LIST, qName);
		try {
			Process p = pb.start();
			BufferedReader results = new BufferedReader(new InputStreamReader(p.getInputStream()));
			boolean error = ProcessUtils.logErrors(p);
			if (error) {
				return;
			}
			String line;
			// read list of ROS parameters and add these to the list of parameters of the
			// describe command
			Ros2ProcessBuilder pbDesc = new Ros2ProcessBuilder(Ros2Constants.PARAM, Ros2Constants.DESCRIBE, qName);
			while (results.ready() && (line = results.readLine()) != null) {
				String param = line.trim();
				pbDesc.command().add(param);
			}
			results.close();

			String paramName = "";
			Class paramSet = ParameterUtils.getParameterClass(component);
			// now obtain type
			Process pDesc = pbDesc.start();
			results = new BufferedReader(new InputStreamReader(pDesc.getInputStream()));
			error = ProcessUtils.logErrors(pDesc);
			while (results.ready() && (line = results.readLine()) != null) {
				String desc = line.trim();
				if (desc.startsWith("Parameter name:")) {
					paramName = desc.substring("Parameter name:".length()).trim();
				}
				if (desc.startsWith("Type:")) {
					String type = desc.substring(5).trim();
					int upper = 1;
					if (type.equals("string array")) { // TODO - right mapping?
						type = "string";
						upper = -1;
					}
					String name = "primitive" + NamedElement.SEPARATOR + type;
					NamedElement ne = ElementUtils.getQualifiedElementFromRS(component, name);
					if (ne == null) {
						if (type.equals("boolean")) {
							type = "bool";
						}
						if (type.equals("integer")) {
							type = "int";
						}
						name = "AnsiCLibrary" + NamedElement.SEPARATOR + type;
						ne = ElementUtils.getQualifiedElementFromRS(component, name);
					}
					Property paramUML = paramSet.createOwnedAttribute(paramName, (Type) ne);
					StereotypeUtil.apply(paramUML, ParameterEntry.class);
					if (upper != 1) {
						paramUML.setUpper(upper);
					}
					if (ne == null) {
						Activator.log.debug(String.format("Cannot find type %s", type));
					}
				}
			}
			results.close();

		} catch (IOException exp) {
			Activator.log.error(exp);
		}
	}
}
