//------------------------------------------------------------------------------
// 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.epf.common.utils.XMLUtil;
import org.eclipse.epf.export.ExportPlugin;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.uma.MethodPlugin;
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$

	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);
			}
		}

		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);
	}
	
}
