/*******************************************************************************
 * Copyright (c) 2002, 2006 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH, 
 * Berlin, Duesseldorf, Frankfurt (Germany) and others.
 *
 * This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
 * 	   IBM Corporation - bug 24108
 *******************************************************************************/

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

import java.io.IOException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Vector;

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

import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * This class can be used to merge the tasks.xml and XDOCtasks.xml. These files can be found in the Ant Editor Content Assist Dev folder. Move the
 * files to the Ant Editor folder to use this class.
 * 
 * The xml automatically generated from the proposed xdoclet in the Apache Ant's project currently has no information on required attributes. In the
 * future the task writers hopefully will include this information in the source code comments. Our template currently inserts an attribute
 * required="NOTDEFINED" and this class replaces that field if its defined in the xml file we have generated from the information based on the html
 * files in the Apache Ant's manual directory.
 */
public class TaskXMLFileMerger {

	// Definitions for the HTML Generated XML File
	public static String HTML_TASKS_DESCRIPTION_XML_FILE_NAME = "/tasks.xml"; //$NON-NLS-1$
	public static String HTML_XML_TAG_TASKS = "TASKS"; //$NON-NLS-1$
	public static String HTML_XML_TAG_TASK = "TASK"; //$NON-NLS-1$
	public static String HTML_XML_TAG_ATTRIBUTE = "ATTRIBUTE"; //$NON-NLS-1$
	// public static String HTML_XML_TAG_DESCRIPTION = "DESCRIPTION";
	public static String HTML_XML_ATTRIBUTE_NAME = "NAME"; //$NON-NLS-1$
	public static String HTML_XML_ATTRIBUTE_REQUIRED = "REQUIRED"; //$NON-NLS-1$

	// Definitions for the XDoclet Genereated XML File
	public static String XDOC_TASKS_DESCRIPTION_XML_FILE_NAME = "/XDOCtasks.xml"; //$NON-NLS-1$
	public static String XDOC_XML_TAG_TASKS = "tasks"; //$NON-NLS-1$
	public static String XDOC_XML_TAG_TASK = "task"; //$NON-NLS-1$
	public static String XDOC_XML_TAG_NAME = "name"; //$NON-NLS-1$
	public static String XDOC_XML_TAG_STRUCTURE = "structure"; //$NON-NLS-1$
	public static String XDOC_XML_TAG_ATTRIBUTES = "attributes"; //$NON-NLS-1$
	public static String XDOC_XML_TAG_ATTRIBUTE = "attribute"; //$NON-NLS-1$
	public static String XDOC_XML_TAG_ELEMENTS = "elements"; //$NON-NLS-1$
	public static String XDOC_XML_TAG_ELEMENT = "element"; //$NON-NLS-1$
	public static String XDOC_XML_TAG_REQUIRED = "required"; //$NON-NLS-1$

	protected NodeList taskNodes_HTML = null;
	protected NodeList taskNodes_XDOC = null;
	public Document xdocXMLDocument = null;

	/**
	 * Creates an initialized instance.
	 */
	public TaskXMLFileMerger() {
		initialize();
	}

	/**
	 * Parses the task description xml files and stores the information.
	 */
	private void initialize() {

		Document tmpDocument = null;

		// Get All the Tasks in the HTML XML Generated file and store in the taskNodes_HTML
		tmpDocument = parseFile(HTML_TASKS_DESCRIPTION_XML_FILE_NAME);
		taskNodes_HTML = tmpDocument.getFirstChild().getChildNodes();

		// Do the same for the XDOC XML Generated file
		tmpDocument = parseFile(XDOC_TASKS_DESCRIPTION_XML_FILE_NAME);
		taskNodes_XDOC = tmpDocument.getFirstChild().getChildNodes();
		xdocXMLDocument = tmpDocument;
		/*
		 * Document tempDocument = parseFile(aFileName); Node tempRootNode = tempDocument.getDocumentElement(); NodeList tempChildNodes =
		 * tempRootNode.getChildNodes(); for(int i=0; i<tempChildNodes.getLength(); i++) { Node tempNode = tempChildNodes.item(i);
		 * if(tempNode.getNodeType() == Node.ELEMENT_NODE) { String tempTagName = tempNode.getNodeName(); if(tempTagName.equals(anXML_TAG_TASK)) {
		 * NamedNodeMap tempAttributes = tempNode.getAttributes(); Node tempAttributeNode = tempAttributes.getNamedItem(anXML_ATTRIBUTE_NAME);
		 * if(tempAttributeNode != null) { String tempTaskName = tempAttributeNode.getNodeValue(); if(tempTaskName != null) {
		 * aHashMap.put(tempTaskName, tempNode); } } } } }
		 */
	}

	/**
	 * This is the function that does all the work. Calling this will cause all Required fields in all Attributes in the XMLDoc file to be replaced
	 * with the value in the corresponding Attributes Required field in the HTML Xml file.
	 */
	public void runReplaceAttributeRequiredProcess() {

		// Iterate over all the tasks. If task is found in sourceList,
		// then iterate over all the attributes, try to find out if the
		// the attribute is required.
		for (int i = 0; i < taskNodes_XDOC.getLength(); ++i) {
			Node tmpTargetNode = taskNodes_XDOC.item(i);

			if (tmpTargetNode.getNodeType() == Node.ELEMENT_NODE) {
				replaceAttributeRequiredInTaskNode(tmpTargetNode);
			}
		}
	}

	private void replaceAttributeRequiredInTaskNode(Node aTargetTaskNode) {

		String tmpTaskName = aTargetTaskNode.getAttributes().getNamedItem(XDOC_XML_TAG_NAME).getNodeValue();

		if (tmpTaskName != null) {
			Node tmpSourceNode = getTaskInHTMLGeneratedTaskListNamed(tmpTaskName);

			if (tmpSourceNode != null) {
				replaceAttributeRequiredInXMLTaskNodeWithAttributeRequiredInHTMLNode(aTargetTaskNode, tmpSourceNode);
			} else {
				System.out.println(MessageFormat.format("Did not find Task \"{0}\" in HTML XML file.", new String[] { tmpTaskName })); //$NON-NLS-1$
			}
		} else {
			System.out.println(MessageFormat.format("Did not find TaskName in TargetTaskNode: {0}", new String[] { aTargetTaskNode.toString() })); //$NON-NLS-1$
		}
	}

	private Node getTaskInHTMLGeneratedTaskListNamed(String aTaskName) {

		for (int i = 0; i < taskNodes_HTML.getLength(); ++i) {

			Node tmpTaskNode = taskNodes_HTML.item(i);
			if (tmpTaskNode.getNodeType() == Node.ELEMENT_NODE) {
				String tmpTagName = tmpTaskNode.getNodeName();
				if (tmpTagName.equals(HTML_XML_TAG_TASK)) {
					NamedNodeMap tmpMap = tmpTaskNode.getAttributes();
					Node tmpNameNode = tmpMap.getNamedItem(HTML_XML_ATTRIBUTE_NAME);
					if (aTaskName.equals(tmpNameNode.getNodeValue())) {
						return tmpTaskNode;
					}
				}
			}
		}
		// Not found
		return null;
	}

	private void replaceAttributeRequiredInXMLTaskNodeWithAttributeRequiredInHTMLNode(Node aTargetTaskNode, Node aSourceTaskNode) {

		Node tmpStructureNode = getChildNodeNamedWithTypeFromNode(XDOC_XML_TAG_STRUCTURE, Node.ELEMENT_NODE, aTargetTaskNode);

		if (tmpStructureNode != null) {
			Node tmpTargetAttributesNode = getChildNodeNamedWithTypeFromNode(XDOC_XML_TAG_ATTRIBUTES, Node.ELEMENT_NODE, tmpStructureNode);
			if (tmpTargetAttributesNode != null) {
				Vector tmpTargetAttributesVector = getAttributeNodesFromXMLAttributesNode(tmpTargetAttributesNode);
				Vector tmpSourceAttributesVector = getAttributeNodesFromHTMLTaskNode(aSourceTaskNode);

				// Iterate over all the attributes in the targetTaskNode
				for (int i = 0; i < tmpTargetAttributesVector.size(); ++i) {
					Node tmpAttributeNode = (Node) tmpTargetAttributesVector.get(i);
					replaceAttributeRequiredInAttributeNodeWithValueFoundInNodeVector(tmpAttributeNode, tmpSourceAttributesVector);
				}
			}
		}
	}

	private void replaceAttributeRequiredInAttributeNodeWithValueFoundInNodeVector(Node aTargetAttributeNode, Vector aSourceAttributeVector) {

		NamedNodeMap tmpTargetNamedNodeMap = aTargetAttributeNode.getAttributes();
		String tmpTargetAttributeName = tmpTargetNamedNodeMap.getNamedItem(XDOC_XML_TAG_NAME).getNodeValue();

		String tmpSourceAttributeName = null;
		String tmpSourceRequiredValue = null;

		for (int i = 0; i < aSourceAttributeVector.size(); ++i) {
			Node tmpSourceAttributeNode = (Node) aSourceAttributeVector.get(i);
			NamedNodeMap tmpSourceAttributeNamedNodeMap = tmpSourceAttributeNode.getAttributes();
			tmpSourceAttributeName = tmpSourceAttributeNamedNodeMap.getNamedItem(HTML_XML_ATTRIBUTE_NAME).getNodeValue();
			// If the Attribute Name is the same we replace the REQUIRED Value
			if (tmpTargetAttributeName.equals(tmpSourceAttributeName)) {
				tmpSourceRequiredValue = tmpSourceAttributeNamedNodeMap.getNamedItem(HTML_XML_ATTRIBUTE_REQUIRED).getNodeValue();
				// Set the Vaule to the on we just got.
				tmpTargetNamedNodeMap.getNamedItem(XDOC_XML_TAG_REQUIRED).setNodeValue(tmpSourceRequiredValue);
			}
		}
	}

	private Vector getAttributeNodesFromXMLAttributesNode(Node anXMLAttributesNode) {

		Vector allAttributes = new Vector();
		NodeList tmpList = anXMLAttributesNode.getChildNodes();

		for (int i = 0; i < tmpList.getLength(); ++i) {
			Node tmpNode = tmpList.item(i);
			if (tmpNode.getNodeType() == Node.ELEMENT_NODE && XDOC_XML_TAG_ATTRIBUTE.equals(tmpNode.getNodeName())) {
				allAttributes.add(tmpNode);
			}
		}
		return allAttributes;
	}

	private Vector getAttributeNodesFromHTMLTaskNode(Node anHTTP_XML_TaskNode) {

		Vector tmpVector = new Vector();
		NodeList tmpList = anHTTP_XML_TaskNode.getChildNodes();

		for (int i = 0; i < tmpList.getLength(); ++i) {
			Node tmpNode = tmpList.item(i);
			if (tmpNode.getNodeType() == Node.ELEMENT_NODE && HTML_XML_TAG_ATTRIBUTE.equals(tmpNode.getNodeName())) {
				tmpVector.add(tmpNode);
			}
		}

		return tmpVector;
	}

	/**
	 * Returns the ChildNode of the node defined by the Arguments. The first child found matching the criterias is returned.
	 * 
	 * @param aNodeName
	 *            The Name of the Node to return.
	 * @param aType
	 *            The Type of the node @see Node
	 * @param aParentNode
	 *            The Node to get the child from
	 * 
	 * @return The First Child Node found matching the criterias, or null if none is found.
	 */
	private Node getChildNodeNamedWithTypeFromNode(String aName, short aNodeType, Node aNode) {

		NodeList tmpNodeList = aNode.getChildNodes();
		for (int i = 0; i < tmpNodeList.getLength(); ++i) {
			Node tmpNode = tmpNodeList.item(i);
			if ((tmpNode.getNodeType() == aNodeType) && aName.equals(tmpNode.getNodeName())) {
				return tmpNode;
			}
		}
		// Not found
		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();
			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;
	}

	/**
	 * This function writes the XMLDocument to the specified file.
	 * 
	 * @param aFileName
	 *            The filename to which the XMLDocument should be written.
	 */
	public void writeXMLDocumentToFile(String aFileName) {

		// try {
		// XmlDocument xmlDocument = (XmlDocument)xdocXMLDocument;
		// xmlDocument.write(new FileWriter(aFileName), "UTF-8"); //$NON-NLS-1$
		// }
		// catch(IOException ioe) {
		// System.out.println(MessageFormat.format(AntEditorToolsMessages.getString("TaskXMLFileMerger.Could_not_print"), new
		// String[]{ioe.toString()})); //$NON-NLS-1$
		// }
	}

	public static void main(String[] args) {

		TaskXMLFileMerger tmpTaskXMLFileMerger = new TaskXMLFileMerger();
		tmpTaskXMLFileMerger.runReplaceAttributeRequiredProcess();
		tmpTaskXMLFileMerger.writeXMLDocumentToFile("src\\anttasks_1.5b.xml"); //$NON-NLS-1$
	}
}
