//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.export.services;

import java.io.File;
import java.io.FileFilter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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

import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.export.ExportPlugin;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.UmaPackage;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * Encapsulates a method library using a DOM document.
 * 
 * @author Jinhua Xi
 * @author Weiping Lu
 * @since 1.0
 */
public class LibraryDocument {

	public static final String TAG_methodPlugins = "methodPlugins"; //$NON-NLS-1$

	public static final String TAG_predefinedConfigurations = "predefinedConfigurations"; //$NON-NLS-1$

	public static final String TAG_resourceDescriptors = "resourceDescriptors"; //$NON-NLS-1$

	public static final String TAG_resourceSubManagers = "subManagers"; //$NON-NLS-1$
	
	public static final String TAG_methodElementProperty = "methodElementProperty"; //$NON-NLS-1$

	public static final String ATTR_href = "href"; //$NON-NLS-1$

	public static final String ATTR_id = "id"; //$NON-NLS-1$

	public static final String ATTR_uri = "uri"; //$NON-NLS-1$

	public static final String ATTR_guid = "guid"; //$NON-NLS-1$
	
	public static final String ATTR_value = "value"; //$NON-NLS-1$

	public static final String exportFile = "export.xmi"; //$NON-NLS-1$

	public static final String libraryFile = "library.xmi"; //$NON-NLS-1$

	public static final String ATTR_name = "name"; //$NON-NLS-1$
	
	protected File libFile;

	protected Document document;

	protected Element libTag = null;

	protected Element resTag = null;
	
	private HashMap guidToUriMap = null;
	
	private Map<String, String> guidToPlugNameMap;

	/**
	 * Creates a new instance.
	 */
	public LibraryDocument(File libFile) throws Exception {
		this.libFile = libFile;
		init();
	}

	private void init() throws Exception {
		this.document = XMLUtil.loadXml(libFile);

		Element root = document.getDocumentElement();
		NodeList nodes = root.getElementsByTagName("org.eclipse.epf.uma:MethodLibrary"); //$NON-NLS-1$
		if (nodes != null && nodes.getLength() > 0) {
			libTag = (Element) nodes.item(0);
		}

		nodes = root
				.getElementsByTagName("org.eclipse.epf.uma.resourcemanager:ResourceManager"); //$NON-NLS-1$
		if (nodes != null && nodes.getLength() > 0) {
			resTag = (Element) nodes.item(0);
		}
	}

    /**
     * Returns the document field
     */
	public Document getDocument() {
		return this.document;
	}

    /**
     * Returns the libFile field
     */
	public File getFile() {
		return libFile;
	}

    /**
     * Returns the libTag field
     */
	public Element getLibTag() {
		return libTag;
	}

    /**
     * Returns the library name
     */
	public String getLibraryName() {
		return libTag.getAttribute("name"); //$NON-NLS-1$
	}

    /**
     * Returns the library guid
     */
	public String getLibraryGuid() {
		return libTag.getAttribute("guid"); //$NON-NLS-1$
	}

    /**
     * Returns the resource tag
     */
	public Element getResourceTag() {
		return resTag;
	}

    /**
     * Removes a plugin node
     */
	public void removePlugin(Element node) {
		libTag.removeChild(node);
	}

    /**
     * Removes a config node
     */
	public void removeConfiguration(Element node) {
		libTag.removeChild(node);
	}

    /**
     * Removes a resource descriptor node
     */
	public void removeResourceDescriptor(Element node) {
		resTag.removeChild(node);
	}

    /**
     * Returns plugin node list
     */
	public NodeList getPlugins() {
		return libTag.getElementsByTagName(TAG_methodPlugins);
	}

    /**
     * Returns configuration node list
     */
	public NodeList getConfigurations() {
		return libTag.getElementsByTagName(TAG_predefinedConfigurations);
	}

    /**
     * Returns resource descriptor node list
     */
	public NodeList getResourceDescriptors() {
		return resTag.getElementsByTagName(TAG_resourceDescriptors);
	}

    /**
     * Returns resource submanager node list
     */
	public NodeList getResourceSubManagers() {
		return resTag.getElementsByTagName(TAG_resourceSubManagers);
	}

    /**
     * Adds a plugin node
     */
	public void addPlugin(Element node) {
		libTag.appendChild(getValidNode(node));
	}

    /**
     * Adds a configuration node
     */
	public void addConfiguration(Element node) {
		libTag.appendChild(getValidNode(node));
	}

    /**
     * Adds a resource node
     */
	public void addResource(Element node) {
		resTag.appendChild(getValidNode(node));
	}

    /**
     * Returns a valid node
     */
	public Node getValidNode(Node node) {
		if (node.getOwnerDocument() == document) {
			return node;
		}

		return document.importNode(node, true);
	}

	/**
	 * remove plugins by guid
	 * 
	 * @param removeList
	 *            List a list of guids
	 */
	public void removePlugins(List removeList) {
		// Importing a package of plgins twice generates 2
		// identical plugins
		// remove the node will cause the node list to shrink, so don't increase
		// the index
		NodeList nodes = getPlugins();
		int i = 0;
		while (i < nodes.getLength()) {
			Element node = (Element) nodes.item(i);
			String guid = getGuid(node);
			if (removeList.contains(guid)) {
				libTag.removeChild(node);
			} else {
				i++;
			}
		}
	}

    /**
     * Remove the list from the configuration nodes
     */
	public void removeConfigurations(List removeList) {
		// remove the unneeded configurations
		NodeList nodes = getConfigurations();
		int i = 0;
		while (i < nodes.getLength()) {
			Element node = (Element) nodes.item(i);
			String guid = getGuid(node);
			if (removeList.contains(guid)) {
				libTag.removeChild(node);
			} else {
				i++;
			}
		}
	}

    /**
     * Remove the list from the resource nodes
     */
	public void removeResourceEntries(List removeList) {
		NodeList nodes = getResourceDescriptors();
		int i = 0;
		while (i < nodes.getLength()) {
			Element node = (Element) nodes.item(i);
			String guid = node.getAttribute(ATTR_id);
			String uri = node.getAttribute(ATTR_uri);
			if (removeList.contains(guid)) {
				resTag.removeChild(node);

				// check the plugin xmi file, if exists, delete the folder
				File plugn_file = getFileFromUri(uri);
				if (plugn_file.exists()) {
					// delete the folder ???
				}
			} else {
				i++;
			}
		}

		// also remove the sub managers
		nodes = getResourceSubManagers();
		i = 0;
		while (i < nodes.getLength()) {
			Element node = (Element) nodes.item(i);
			String guid = getSubManagerBaseGuid(node.getAttribute(ATTR_href));
			if (removeList.contains(guid)) {
				resTag.removeChild(node);
			} else {
				i++;
			}
		}
	}

	/**
	 * get the resource uri for the resource guid
	 * @param guid
	 * @return String the uri
	 */
	public String getResourceUri(String guid) {
		String uri = getUriFromGuidToUriMap(guid);
		if (uri == null) {
			uri = getResourceUri_(guid);
			if (uri != null) {
				//addToGuidToUriMap(guid, uri);
			}
		}
		return uri;
	}
	
	private String getResourceUri_(String guid) {
	
		NodeList nodes = getResourceDescriptors();
		for (int i = 0; i < nodes.getLength(); i++ ) {
			Element node = (Element) nodes.item(i);
			String id = node.getAttribute(ATTR_id);
			String uri = node.getAttribute(ATTR_uri);
			if ( guid.equals(id) ) {
				return decodeUri(uri);
			}
		}
		
		return null;
	}

	/**
	 * Returns the decored URI.
	 */
	public String decodeUri(String uri) {
		try {
			uri = URLDecoder.decode(uri, "UTF-8"); //$NON-NLS-1$
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		return uri;
	}
	
	/**
	 * Returns the file given the uri.
	 */
	public File getFileFromUri(String uri) {
		uri = decodeUri(uri);
		
		int i = uri.indexOf("#"); //$NON-NLS-1$
		if (i > 0) {
			uri = uri.substring(0, i);
		}

		return new File(libFile.getParentFile(), uri);
	}

	/**
	 * Saves the document.
	 */
	public void save() throws Exception {
		saveAs(libFile.getAbsolutePath());
	}

	/**
	 * Saves the document in the file given by filePathName.
	 */
	public void saveAs(String filePathName) throws Exception {
		XMLUtil.saveDocument(this.document, filePathName);
	}

	/**
	 * Is the document for configutation specification export/import only?
	 */
	public boolean isConfigSpecsOnly() {
		NodeList nodes = getPlugins();
		if (nodes == null || nodes.getLength() == 0) {
			return true;
		}

		for (int i = 0; i < nodes.getLength(); i++) {
			Element node = (Element) nodes.item(i);
			String href = node.getAttribute(LibraryDocument.ATTR_href);
			String guid = getGuidFromHref(href);
			String uri = getResourceUri(guid);
			
			// check if the resource files are there
			File plugn_file = getFileFromUri(uri);
			if (plugn_file.exists()) {
				return false;
			}
		}

		return true;
	}

	// static hlper methods /////////////////////////////////////
	/**
	 * Returns submanager's base guid.
	 */
	public static String getSubManagerBaseGuid(String href) {
		final Pattern p = Pattern.compile(
				"uma://(.*?)#(.*?)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
		Matcher m = p.matcher(href);
		if (m.find()) {
			return m.group(1);
		}

		return href;
	}

	/**
	 * Returns child value of the child tag given by childTagName.
	 */
	public static String getChildValue(Element tag, String childTagName) {
		NodeList nodes = tag.getChildNodes();
		if (nodes == null || nodes.getLength() == 0) {
			return ""; //$NON-NLS-1$
		}

		int size = nodes.getLength();
		for (int i = 0; i < size; i++) {
			Node node = nodes.item(i);
			if ((node instanceof Element)
					&& ((Element) node).getTagName().equals(childTagName)) {
				return getNodeText((Element) node);
			}
		}

		return ""; //$NON-NLS-1$
	}

	/**
	 * text of a leaf node, without child element
	 * 
	 * @param tag
	 * @return
	 */
	public static String getNodeText(Element tag) {

		NodeList nodes = tag.getChildNodes();
		if (nodes == null || nodes.getLength() == 0) {
			return ""; //$NON-NLS-1$
		}

		int size = nodes.getLength();
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < size; i++) {
			Node node = nodes.item(i);
			if (node.getNodeType() == Node.TEXT_NODE) {
				buffer.append(node.getNodeValue());
			}
		}

		return buffer.toString();
	}

	/**
	 * Returns guid from href.
	 */
	public static String getGuidFromHref(String href) {
		int i = href.indexOf("#"); //$NON-NLS-1$
		if (i > 0) {
			return href.substring(i + 1);
		}

		return href;
	}

	/**
	 * Returns guid of the node.
	 */
	public static String getGuid(Element node) {
		String id = node.getAttribute("xmi:id"); //$NON-NLS-1$
		if ( id == null || id.length() == 0 ) {
			String href = node.getAttribute(ATTR_href);
			id = getGuidFromHref(href);
		}
		
		return id;
	}
	
	// 143033 - update config specs' importing and exporting to match with the new file format
	protected Element getConfigNode(Element configNode) {
		try {
			
			// new model defines href for configuration 
			String href = configNode.getAttribute(ATTR_href);
			if (href == null || href.length() == 0 ) {
				return configNode;
			} 

			String guid = getGuidFromHref(href);
			String uri = getResourceUri(guid);
			if ( uri == null ) {
				return configNode;
			}
			
			File source = getFileFromUri(uri);
			Document document = XMLUtil.loadXml(source);
			Element root = document.getDocumentElement();

			Element configTag = null;
			if (root.getTagName().equals("org.eclipse.epf.uma:MethodConfiguration")) //$NON-NLS-1$
			{
				configTag = root;
			} else {
				NodeList nodes = root
						.getElementsByTagName("org.eclipse.epf.uma:MethodConfiguration"); //$NON-NLS-1$
				if (nodes.getLength() > 0) {
					configTag = (Element) nodes.item(0);
				}
			}
			
			return configTag;

		} catch (Exception e) {
			ExportPlugin.getDefault().getLogger().logError(e);
		}
		
		return configNode;
	}
	
	/**
	 * Returns ConfigurationSpec instance given the element node config.
	 */
	public ConfigurationSpec getConfigurationSpec(Element config) {
		ConfigurationSpec spec = new ConfigurationSpec();
		
		Element configNode = getConfigNode(config);
		spec.guid = configNode.getAttribute("xmi:id"); //$NON-NLS-1$
		spec.name = configNode.getAttribute("name"); //$NON-NLS-1$
		spec.brief_desc = configNode.getAttribute("briefDescription"); //$NON-NLS-1$
		
		// get plugins
		NodeList nodes = configNode.getElementsByTagName("methodPluginSelection"); //$NON-NLS-1$
		if (nodes != null) {
			for (int i = 0; i < nodes.getLength(); i++) {
				Element node = (Element) nodes.item(i);
				String guid = getGuidFromHref(node.getAttribute(ATTR_href));
				spec.pluginIds.add(guid);
			}
		}

		// get packages
		nodes = configNode.getElementsByTagName("methodPackageSelection"); //$NON-NLS-1$
		if (nodes != null) {
			for (int i = 0; i < nodes.getLength(); i++) {
				Element node = (Element) nodes.item(i);
				String guid = getGuidFromHref(node.getAttribute(ATTR_href));
				spec.packageIds.add(guid);
			}
		}

		// get views
		nodes = configNode.getElementsByTagName("processViews"); //$NON-NLS-1$
		if (nodes != null) {
			for (int i = 0; i < nodes.getLength(); i++) {
				Element node = (Element) nodes.item(i);
				String guid = getGuidFromHref(node.getAttribute(ATTR_href));
				spec.viewIds.add(guid);
			}
		}

		// get meps
		nodes = configNode.getElementsByTagName(TAG_methodElementProperty); //$NON-NLS-1$
		if (nodes != null) {
			for (int i = 0; i < nodes.getLength(); i++) {
				Element node = (Element) nodes.item(i);
				String name = node.getAttribute(ATTR_name);
				String value = node.getAttribute(ATTR_value);
				MethodElementProperty mep = (MethodElementProperty) EcoreUtil
						.create(UmaPackage.eINSTANCE.getMethodElementProperty());
				mep.setName(name);
				mep.setValue(value);
				spec.mepList.add(mep);
			}
		}
		
		return spec;
	}
	
	/**
	 * Adds guid/uri pair to guidToUriMap.
	 */
	public void addToGuidToUriMap(String guid, String uri) {
		if (guidToUriMap == null) {
			guidToUriMap = new HashMap();
		}
		guidToUriMap.put(guid, uri);
	}
	
	/**
	 * Gets uri from guid.
	 */
	public String getUriFromGuidToUriMap(String guid) {
		return guidToUriMap == null ? null : (String) guidToUriMap.get(guid);
	}
	
	/**
	 * Create an instance.
	 */
	public static class ConfigDocVisitor {
		public void visit(File file, Element node) {			
		}
	}
	
	/**
	 * Visit configuration files given by the configuration file folder configDir.
	 */
	public static void visitConfigFiles(File configDir, ConfigDocVisitor visitor) {	
		FileFilter filter = new FileFilter() {
			public boolean accept(File pathname) {
				return !pathname.getName().equalsIgnoreCase("cvs") && 		//$NON-NLS-1$
						pathname.isDirectory() || pathname.getName().endsWith(MultiFileSaveUtil.DEFAULT_FILE_EXTENSION);
			}			
		};		
		File[] files = configDir.listFiles(filter);
		if (files == null) {
			return;
		}
		for (int i=0; i<files.length; i++) {
			File file = files[i];
			try {
				DocumentBuilder builder = DocumentBuilderFactory.newInstance()
						.newDocumentBuilder();
				Document doc = builder.parse(file);
				Element root = doc.getDocumentElement();
				visitor.visit(file, root);				
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}		
	}
	
	/**
	 * Build a map from pluign guids to resource manager guids.
	 */
	public Map buildPluginGuidToResMgrGuidMap(List pluginGuids) {
		if (pluginGuids == null || pluginGuids.size() == 0) {
			return null;
		}
		NodeList subMgrs = getResourceSubManagers();
		if (subMgrs == null || subMgrs.getLength() == 0) {
			return null;
		}				
		HashMap pluginGuidToResMgrGuidMap = new HashMap();
		for (int i=0; i<pluginGuids.size(); i++) {			
			String pluginGuid = (String) pluginGuids.get(i);
			pluginGuidToResMgrGuidMap.put(pluginGuid, null);
		}
		boolean isEmpty = true;
		for (int i=0; i<subMgrs.getLength(); i++) {			
			Element mgr = (Element) subMgrs.item(i);
			String  href = mgr.getAttribute(ATTR_href);
			String pluginGuid = getSubManagerBaseGuid(href);
			if (pluginGuidToResMgrGuidMap.containsKey(pluginGuid)) {
				pluginGuidToResMgrGuidMap.put(pluginGuid, getGuidFromHref(href));
				isEmpty = false;
			}
		}		
		return isEmpty ?  null : pluginGuidToResMgrGuidMap;
	}
	
	/**
	 * Save extra info (all plugin guids and names) in libTag's MethodElementProperty
	 */
	public void storeExtraInfo(List<MethodPlugin> plugins) {
		if (plugins == null) {
			return;
		}		

		Element versionNode = document.createElement(TAG_methodElementProperty);
		versionNode.setAttribute(ATTR_value, "0");	//$NON-NLS-1$ 
		libTag.appendChild(versionNode);		
		
		for (Iterator<MethodPlugin> it = plugins.iterator(); it.hasNext();) {
			MethodPlugin plug = it.next();
			
			Element guidNode = document.createElement(TAG_methodElementProperty);	
			guidNode.setAttribute(ATTR_value, plug.getGuid());
			Element nameNode = document.createElement(TAG_methodElementProperty);	
			nameNode.setAttribute(ATTR_value, plug.getName());
			
			libTag.appendChild(guidNode);
			libTag.appendChild(nameNode);
		}
		
	}	
	
	private void recallExtraInfo() {
		try {
			NodeList nodes = getMethodElementProperties();
			if (nodes == null || nodes.getLength() == 0) {
				return;
			}
			Element versionNode = (Element) nodes.item(0);
			String versionStr = versionNode.getAttribute(ATTR_value);
			
			if (versionStr.equals("0")) { //$NON-NLS-1$ 
				guidToPlugNameMap = new HashMap<String, String>();
				for (int i = 1; i < nodes.getLength();) {
					Element node = (Element) nodes.item(i);
					String guid = node.getAttribute(ATTR_value);
					node = (Element) nodes.item(i + 1);
					String name = node.getAttribute(ATTR_value);
					guidToPlugNameMap.put(guid, name);
					if (false) {				
						System.out.println("LD> guid: " + guid); //$NON-NLS-1$
						System.out.println("LD> name: " + name); //$NON-NLS-1$
					}					
					i += 2;
				}
			}
		} catch (Throwable e) {
			e.printStackTrace();
			guidToPlugNameMap = null;
		}
		
	}
	
	/**
	 * Get guid to plugin map
	 */
	public Map<String, String> getGuidToPlugNameMap() {
		if (guidToPlugNameMap == null) {
			recallExtraInfo();
		}		
		return guidToPlugNameMap;
	}
	
    /**
     * Returns methodElementProperty node list
     */
	private NodeList getMethodElementProperties() {
		return libTag.getElementsByTagName(TAG_methodElementProperty);
	}
	
}
