/*******************************************************************************
 * Copyright (c) 2018, MDH 
 *
 * 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/org/documents/epl-2.0/EPL-2.0.html
 *
 * SPDX-License-Identifier: EPL-2.0
 *  
 *   Contributors: 
 *   Muhammad Atif Javed
 *   Initial API and implementation and/or initial documentation
 *******************************************************************************/
/**
 */
package org.eclipse.opencert.lines.resolving;

import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

import java.util.List;
import java.util.Stack;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.project.MethodLibraryProject;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.opencert.lines.resolving.LibraryDocument;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerException;

/**
 * Resolve problems with the XMI files.
 */
public class DoResolve {
	
	public static final String libraryFile = "library.xmi";
	final static Pattern p = Pattern.compile(
			"uma://(.*?)#(.*?)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
	
	protected static List<File> fileList = new ArrayList<File>();
	
	protected static Document document;
	protected static LibraryDocument libDocument;
	
	private static Stack<File> xmiStack = new Stack<File>();
	private static List<String> capabilitypatterns = new ArrayList<String>();
	private static HashMap<String, String> idToUriMap = new HashMap<String, String>();
	private static HashMap<String, String> platformResourcePath = new HashMap<String, String>();
	
	public static void Resolve(String dirPath) throws Exception {
		
		String filePath = dirPath + "/library.xmi";
		GetAllXMIFiles(new File(dirPath), fileList, true);
		
		if (!dirPath.equals(filePath)) {
			libDocument = new LibraryDocument(new File(filePath));
			libDocument.init();
			
			NodeList nodes = libDocument.getResourceDescriptors();
			ResourceDescriptors(filePath, nodes);
			
			document = XMLUtil.loadXml(new File(filePath));
			Element root = document.getDocumentElement();
			Uris(filePath, root.getElementsByTagName("subManagers"));
			Uris(filePath, root.getElementsByTagName("methodPlugins"));
			
		}
		
		while(!xmiStack.isEmpty()){
			File xmiFile = xmiStack.pop();
			document = XMLUtil.loadXml(xmiFile);
			
			String path = xmiFile.getAbsolutePath();
			Element root = document.getDocumentElement();
			
			NodeList nodes = root.getElementsByTagName("resourceDescriptors");
			ResourceDescriptors(path, nodes);
			
			if(xmiFile.getName().matches("plugin.xmi")){
				ResolvePluginReferences(path, root);
			}else if(xmiFile.getName().matches("model.xmi")){
				ResolveModelReferences(path, root);
			}
		}
		ResolveConfigurationReferences(dirPath +"/configurations");		
	}
	
	public static void ResolvePluginReferences(String path, Element root) throws Exception{
		
		Uris(path, root.getElementsByTagName("subManagers"));
		Uris(path, root.getElementsByTagName("presentation"));
		Uris(path, root.getElementsByTagName("categorizedElements"));
		
		ChildUris(path, root.getElementsByTagName("methodPackages"));
		
		PlatformResourcePaths(path, root.getElementsByTagName("bases"));
		PlatformResourcePaths(path, root.getElementsByTagName("activityReferences"));
		PlatformResourcePaths(path, root.getElementsByTagName("variabilityBasedOnElement"));
	}
	
	public static void ResolveModelReferences(String path, Element root) throws Exception{
		Uris(path, root.getElementsByTagName("presentation"));
		Uris(path, root.getElementsByTagName("includesPatterns"));
		Uris(path, root.getElementsByTagName("variabilityBasedOnElement"));
		Uris(path, root.getElementsByTagName("includesPatterns"));
		
		PlatformResourcePaths(path, root.getElementsByTagName("Task"));
		PlatformResourcePaths(path, root.getElementsByTagName("Role"));
		PlatformResourcePaths(path, root.getElementsByTagName("WorkProduct"));	
		PlatformResourcePaths(path, root.getElementsByTagName("toolmentor"));
		
		PlatformResourcePaths(path, root.getElementsByTagName("selectedSteps"));
	}
	
	public static void ResolveConfigurationReferences(String configPath) throws Exception{
		List<File> configs = new ArrayList<File>();
		FileUtil.getAllFiles(new File(configPath), configs, true);
		
		for(int i=0; i<configs.size(); i++){
			document = XMLUtil.loadXml(configs.get(i));
			String path = configs.get(i).getAbsolutePath();
			Element root = document.getDocumentElement();
			
			PlatformResourcePaths(path, root.getElementsByTagName("processViews"));
			PlatformResourcePaths(path, root.getElementsByTagName("methodPluginSelection"));
			PlatformResourcePaths(path, root.getElementsByTagName("methodPackageSelection"));
		}
	}
	
	public static void ResourceDescriptors(String filePath, NodeList nodes) throws Exception{
		String pathName = null;
		for (int i = 0; i < nodes.getLength(); i++ ) {
			Element node = (Element) nodes.item(i);
			
			String normalizedPath = filePath.replace('\\', '/');
			String id = node.getAttribute("id");
			String uri = node.getAttribute("uri");

			if (!uri.isEmpty()) {
				idToUriMap.put(id, uri);
				
				int pathIndex = normalizedPath.lastIndexOf("/"); //$NON-NLS-1$
				if (pathIndex > 0) {
					String dir = normalizedPath.substring(0, pathIndex);
					pathName = StrUtil.replace(dir + "/"+uri+"", "%20", " ");
					
					File xmiFile = new File(pathName);
					xmiStack.push(xmiFile);
					
					if (pathName.contains("capabilitypatterns")){
						capabilitypatterns.add(pathName);
					}
				}
			}
		}
	}

	public static void Uris(String filePath, NodeList nodes){
		for (int i = 0; i < nodes.getLength(); i++ ) {
			Element node = (Element) nodes.item(i);
			
			String href = node.getAttribute("href");
			
			Matcher m = p.matcher(href);
			if (m.find()) {
				int index = href.indexOf("#");
				if (index > 0) {
					String uri = (String)idToUriMap.get(m.group(1));
					String bindId =	href.substring(index + 0);
					
					if(uri.contains("%20")){
						uri = StrUtil.replace(uri, "%20", " ");
					}
					
					if(uri.startsWith("capabilitypatterns")){
						PlatformResourcePaths(filePath, nodes);
					}else{
						transform(filePath, node, uri+bindId);
					}
				}
			}	
		}
	}
	
	public static void ChildUris(String filePath, NodeList nodes){
		for (int i = 0; i < nodes.getLength(); i++ ) {
			Element node = (Element) nodes.item(i);
			NodeList childNodes = node.getElementsByTagName("childPackages");
			for (int j = 0; j < childNodes.getLength(); j++ ) {
				Element childNode = (Element) childNodes.item(j);
				String href = childNode.getAttribute("href");
				
				Matcher m = p.matcher(href);
				if (m.find()) {
					int index = href.indexOf("#");
					if (index > 0) {
						String uri = (String)idToUriMap.get(m.group(1));
						String bindId =	href.substring(index + 0);
						transform(filePath, childNode, uri+bindId);
					}
				}
				
			}
		}
	}
	
	public static void PlatformResourcePaths(String filePath, NodeList nodes){
		for (int i = 0; i < nodes.getLength(); i++ ) {
			Element node = (Element) nodes.item(i);
			
			String href = node.getAttribute("href");
			Matcher m = p.matcher(href);
			if (m.find()) {
				int index = href.indexOf("#");
				if (index > 0) {
					String uri = (String)platformResourcePath.get(m.group(1));
					
					String bindId =	href.substring(index + 0);
					if(uri.contains("%20")){
						uri = StrUtil.replace(uri, "%20", " ");
					}	
					transform(filePath, node, uri+bindId);
				}
			}	
		}
	}
	
	public static void transform(String filePath, Node node, String nodeValue) {
		TransformerFactory factory = TransformerFactory.newInstance();
		Transformer transformer;
		
		try {
			transformer = factory.newTransformer();
			for (int i = 0; i < node.getAttributes().getLength(); i++) {
				
				Node item = node.getAttributes().item(i);
				if(node.getAttributes().item(i).getNodeName().equals("href")){
					item.setNodeValue(nodeValue);
					
					OutputStreamWriter writer = new OutputStreamWriter(
							new FileOutputStream(new File(filePath)), "utf-8");
					
					transformer.setParameter("href", nodeValue);
					Source input = new DOMSource(document);
					Result output = new StreamResult(new File(filePath));
				    
				    transformer.transform(input, output);
				    
				    writer.flush();
				    writer.close();
				}
				
			}
		} catch (IOException | TransformerException e) {
			e.printStackTrace();
		}
	}
	
	public static void GetAllXMIFiles(File path, List<File> fileList,
			boolean recursive) throws Exception {
		if (path.isDirectory()) {
			File[] files = path.listFiles();
			if (files != null) {
				for (int i = 0; i < files.length; i++) {
					if (files[i].isFile()) {
						String name = files[i].getName();
						if (name.lastIndexOf(".") != -1)
							if (name
									.substring(name.lastIndexOf(".") + 1).matches("xmi")) {
								fileList.add(files[i]);
								GetResourcePaths(files[i], "org.eclipse.epf.uma:MethodPlugin");
								GetResourcePaths(files[i], "org.eclipse.epf.uma:ProcessComponent");
								
								String absPath = path.getAbsolutePath();
								if(absPath.substring(absPath.lastIndexOf("\\") + 1).matches("tasks")){
									GetResourcePaths(files[i], "org.eclipse.epf.uma:TaskDescription");
								}
							}
					} else if (recursive) {
						GetAllXMIFiles(files[i], fileList, recursive);
					}
				}
			}
		}
	}
	
	public static void GetResourcePaths(File file, String tag) throws Exception{
		document = XMLUtil.loadXml(file);
		
		MethodLibrary library = LibraryService.getInstance().getCurrentMethodLibrary();
		IProject project = MethodLibraryProject.findProject(library);
		IPath path = project.getFullPath();
		
		Element root = document.getDocumentElement();
		String filePath = file.getAbsolutePath();
		String normalizedPath = filePath.replace('\\', '/');
		
		int projIndex = normalizedPath.indexOf("/error_free_models");
		String platformPath = "platform:/resource"+path.toString()+normalizedPath
				.substring(projIndex + 0);

		if (!root.toString().contains(tag)){
			NodeList nodes = root.getElementsByTagName(tag);
			for (int j = 0; j < nodes.getLength(); j++ ) {
				Element node = (Element) nodes.item(j);
				String processId = node.getAttribute("xmi:id");
				platformResourcePath.put(processId, platformPath);
			}
		}else{
			String processId = root.getAttribute("xmi:id");							
			platformResourcePath.put(processId, platformPath);
		}
	}
}