/*******************************************************************************
 * Copyright (c) 2002, 2013 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH, 
 * Berlin, Duesseldorf, Frankfurt (Germany) 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:
 *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
 * 	   IBM Corporation - bug fixes
 *******************************************************************************/

package org.eclipse.ant.internal.ui.editor;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

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

import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IProgressService;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * The <code>TaskDescriptionProvider</code> provides the additional descriptions for tasks and attributes for the code assist.
 * <P>
 * Descriptions for task are originally provided with the XML file <code>TASKS_DESCRIPTION_XML_FILE_NAME</code>. This file is parsed by the provider
 * and requested descriptions are returned.
 * <P>
 */
public class TaskDescriptionProvider {

	/**
	 * The file that contains all task descriptions.
	 */
	public static final String TASKS_DESCRIPTION_XML_FILE_NAME = "/org/eclipse/ant/internal/ui/editor/anttasks_1.6.0.xml"; //$NON-NLS-1$

	public static final String XML_TAG_TASKS = "tasks"; //$NON-NLS-1$
	public static final String XML_TAG_TASK = "task"; //$NON-NLS-1$
	public static final String XML_TAG_ELEMENTS = "elements"; //$NON-NLS-1$
	public static final String XML_TAG_ATTRIBUTE = "attribute"; //$NON-NLS-1$
	public static final String XML_TAG_ATTRIBUTES = "attributes"; //$NON-NLS-1$
	public static final String XML_TAG_ELEMENT = "element"; //$NON-NLS-1$
	public static final String XML_TAG_STRUCTURE = "structure"; //$NON-NLS-1$
	public static final String XML_ATTRIBUTE_REQUIRED = "required"; //$NON-NLS-1$

	/**
	 * Class to avoid holding on to DOM element handles
	 * 
	 * @since 3.5
	 */
	class ProposalNode {
		String desc = null;
		String required = null;
		HashMap<String, ProposalNode> nodes = null;

		ProposalNode(String desc, String required) {
			this.desc = desc;
			this.required = required;
		}

		void addChild(String name, ProposalNode node) {
			if (nodes == null) {
				nodes = new HashMap<String, ProposalNode>(9);
			}
			nodes.put(name, node);
		}

		ProposalNode getChild(String name) {
			if (nodes != null) {
				return nodes.get(name);
			}
			return null;
		}
	}

	private static TaskDescriptionProvider fgDefault;

	/**
	 * Mapping of {@link String} to {@link ProposalNode} <br>
	 * <br>
	 * <code>Map&lt;String, ProposalNode&gt;</code>
	 */
	private Map<String, ProposalNode> taskNodes = null;

	/**
	 * Meant to be a singleton
	 */
	private TaskDescriptionProvider() {
	}

	public static TaskDescriptionProvider getDefault() {
		if (fgDefault == null) {
			fgDefault = new TaskDescriptionProvider();
			IRunnableWithProgress runnable = new IRunnableWithProgress() {
				@Override
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					fgDefault.initialize();
				}
			};

			IProgressService service = PlatformUI.getWorkbench().getProgressService();
			try {
				service.busyCursorWhile(runnable);
			}
			catch (InvocationTargetException e) {
				// do nothing
			}
			catch (InterruptedException e) {
				// do nothing
			}
		}
		return fgDefault;
	}

	/**
	 * Parses the task description XML file and stores the information.
	 */
	protected void initialize() {
		taskNodes = new HashMap<String, ProposalNode>();
		Document doc = parseFile(TASKS_DESCRIPTION_XML_FILE_NAME);
		Node root = doc.getDocumentElement();
		NodeList tasks = root.getChildNodes();
		Node node = null;
		for (int i = 0; i < tasks.getLength(); i++) {
			node = tasks.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				if (XML_TAG_TASK.equals(node.getNodeName())) {
					Element task = (Element) node;
					String name = task.getAttribute(IAntCoreConstants.NAME);
					if (name != null) {
						ProposalNode tasknode = new ProposalNode(getDescription(task), null);
						taskNodes.put(name, tasknode);
						NodeList nodes = task.getElementsByTagName(XML_TAG_ATTRIBUTE);
						Element e = null;
						for (int j = 0; j < nodes.getLength(); j++) {
							e = (Element) nodes.item(j);
							addNode(e, tasknode);
						}
						nodes = task.getElementsByTagName(XML_TAG_ELEMENT);
						for (int j = 0; j < nodes.getLength(); j++) {
							e = (Element) nodes.item(j);
							addNode(e, tasknode);
						}
					}
				}
			}
		}
	}

	/**
	 * Adds a new child {@link ProposalNode} to the given parent node
	 * 
	 * @param element
	 * @param node
	 * @since 3.5
	 */
	void addNode(Element element, ProposalNode node) {
		String name = element.getAttribute(IAntCoreConstants.NAME);
		if (name != null) {
			node.addChild(name, new ProposalNode(getDescription(element), element.getAttribute(XML_ATTRIBUTE_REQUIRED)));
		}
	}

	/**
	 * Recursively find the description text for the parent {@link Element}
	 * 
	 * @param element
	 * @return the description element text or <code>null</code>
	 * @since 3.5
	 */
	String getDescription(Element element) {
		NodeList nodes = element.getChildNodes();
		for (int i = 0; i < nodes.getLength(); i++) {
			Node node = nodes.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE && IAntCoreConstants.DESCRIPTION.equals(node.getNodeName())) {
				node = node.getFirstChild();
				if (node != null) {
					return node.getNodeValue();
				}
			}
		}
		return null;
	}

	/**
	 * Returns the (DOM) document as a result of parsing the file with the specified file name.
	 * <P>
	 * The file will be loaded as resource, thus must begin with '/' and must be relative to the classpath.
	 */
	private Document parseFile(String aFileName) {
		Document tempDocument = null;

		DocumentBuilderFactory tempFactory = DocumentBuilderFactory.newInstance();
		tempFactory.setIgnoringComments(true);
		tempFactory.setIgnoringElementContentWhitespace(true);
		tempFactory.setCoalescing(true);

		try {
			DocumentBuilder tempDocBuilder = tempFactory.newDocumentBuilder();
			tempDocBuilder.setErrorHandler(new DefaultHandler());
			URL tempURL = getClass().getResource(aFileName);
			InputSource tempInputSource = new InputSource(tempURL.toExternalForm());
			tempDocument = tempDocBuilder.parse(tempInputSource);
		}
		catch (ParserConfigurationException e) {
			AntUIPlugin.log(e);
		}
		catch (IOException ioException) {
			AntUIPlugin.log(ioException);
		}
		catch (SAXException saxException) {
			AntUIPlugin.log(saxException);
		}

		return tempDocument;
	}

	/**
	 * Returns the description string for the specified task.
	 * 
	 * @return description string or <code>null</code> if task not known or no description available.
	 */
	public String getDescriptionForTask(String aTaskName) {
		ProposalNode task = taskNodes.get(aTaskName);
		if (task != null) {
			return task.desc;
		}
		return null;
	}

	/**
	 * Returns the description string for the specified attribute of the specified task.
	 * 
	 * @return description string or <code>null</code> if task or attribute not known or no description available.
	 */
	public String getDescriptionForTaskAttribute(String aTaskName, String anAttributeName) {
		ProposalNode task = taskNodes.get(aTaskName);
		if (task != null) {
			ProposalNode att = task.getChild(anAttributeName);
			if (att != null) {
				return att.desc;
			}
		}
		return null;
	}

	/**
	 * Returns the required string value for the specified attribute of the specified task.
	 * 
	 * @return required string or <code>null</code> if task or attribute not known or no description available.
	 */
	public String getRequiredAttributeForTaskAttribute(String aTaskName, String anAttributeName) {
		ProposalNode task = taskNodes.get(aTaskName);
		if (task != null) {
			ProposalNode att = task.getChild(anAttributeName);
			if (att != null) {
				return att.required;
			}
		}
		return null;
	}

	/**
	 * Returns the {@link ProposalNode} for the given task name or <code>null</code> if one does not exist
	 * 
	 * @param aTaskName
	 * @return the {@link ProposalNode} for the given name or <code>null</code>
	 * @since 3.5
	 */
	ProposalNode getTaskNode(String aTaskName) {
		return taskNodes.get(aTaskName);
	}

	protected static void reset() {
		if (fgDefault != null && fgDefault.taskNodes != null) {
			fgDefault.taskNodes.clear();
		}
		fgDefault = null;
	}
}