//------------------------------------------------------------------------------
// 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.library.edit.util.MethodLibraryPropUtil;
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;
	
	private int synFreeLibIx = -1; //-1: unset, 0: false, 1: true;

	/**
	 * 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;
			}
			int ix = -1;
			for (int i = 0; i < nodes.getLength(); i++) {
				Element node = (Element) nodes.item(i);
				String name = node.getAttribute(ATTR_name);
				if (name ==null || name.trim().length() == 0) {
					ix = i;
					break;
				}
			}
			if (ix == -1) {
				return;
			}
			
			Element versionNode = (Element) nodes.item(ix);
			String versionStr = versionNode.getAttribute(ATTR_value);
			
			if (versionStr.equals("0")) { //$NON-NLS-1$ 
				guidToPlugNameMap = new HashMap<String, String>();
				for (int i = ix + 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);
	}
	
	public boolean isSynFreeLib() {
		if (synFreeLibIx == -1) {
			synFreeLibIx = 0;
			
			NodeList nodes = getMethodElementProperties();
			if (nodes != null) {
				for (int i = 0; i < nodes.getLength(); i++) {
					Element node = (Element) nodes.item(i);
					String name = node.getAttribute(ATTR_name);
					if (name != null && name.equals(MethodLibraryPropUtil.Library_SynFree)) {
						String value = node.getAttribute(ATTR_value);
						synFreeLibIx = Boolean.parseBoolean(value) ? 1 : 0;
						break;
					}
				}
			}
		}
		return synFreeLibIx > 0;
	}

	
}
