/*******************************************************************************
 * 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 com.ibm.icu.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$
	}
}
