/*******************************************************************************
 * Copyright (c) 2008, 2016 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 API and implementation
 *******************************************************************************/
package org.eclipse.swt.tools.internal;

import java.io.*;
import java.util.*;

import org.w3c.dom.*;

public class DOMWriter {

	static String ENCONDING = "UTF8";
	PrintStream out;
	String[] attributeFilter;
	String[] idAttributes;
	String nodeFilter;

	public DOMWriter(PrintStream out) {
		this.out = new PrintStream(out);
	}

	String nodeName(Node node) {
		// TODO use getLocalName()?
		return node.getNodeName();
	}
	
	boolean filter(Attr attr) {
		if (attributeFilter == null) return false;
		String name = attr.getNodeName();
		for (int i = 0; i < attributeFilter.length; i++) {
			if (name.matches(attributeFilter[i])) return false;
		}
		return true;
	}
	
	Node getIDAttribute(Node node) {
		NamedNodeMap attributes = node.getAttributes();
		if (attributes == null) return null;
		String[] names = idAttributes;
		for (int i = 0; i < names.length; i++) {
			Node nameAttrib = attributes.getNamedItem(names[i]);
			if (nameAttrib != null) return nameAttrib;
		}
		return null;
	}
	
	void print(String str) {
		out.print(str);
	}
	void println() {
		out.println();
	}

	public void print(Node node) {
		print(node, 0);
	}
	
	public void print(Node node, int level) {
		if (node == null)
			return;
		int type = node.getNodeType();
		switch (type) {
			case Node.DOCUMENT_NODE: {
				print("<?xml version=\"1.0\" encoding=\"");
				print(ENCONDING);
				print("\"?>");
				println();
				print(((Document) node).getDocumentElement());
				break;
			}
			case Node.ELEMENT_NODE: {
				Attr attrs[] = sort(node.getAttributes());
				String name = nodeName(node);
				boolean isArg = name.equals("arg");
				boolean gen = isArg || name.equals("retval");
				for (int i = 0; i < attrs.length && !gen; i++) {
					Attr attr = attrs[i];
					if (nodeName(attr).startsWith(nodeFilter)) gen = true;
				}
				if (!gen) break;
				for (int i = 0; i < level; i++) print("\t");
				print("<");
				print(name);
				for (int i = 0; i < attrs.length; i++) {
					Attr attr = attrs[i];
					if (isArg && "name".equals(attr.getNodeName())) continue;
					if (filter(attr)) continue;
					print(" ");
					print(nodeName(attr));
					print("=\"");
					print(normalize(attr.getNodeValue()));
					print("\"");
				}
				print(">");
				NodeList children = node.getChildNodes();
				if (children != null) {
					int len = children.getLength();
					List<Node> nodes = new ArrayList<>();
					for (int i = 0; i < len; i++) {
						Node child = children.item(i);
						if (child.getNodeType() == Node.ELEMENT_NODE) nodes.add(child);
					}
					int count = nodes.size();
					Collections.sort(nodes, (a, b) -> {
						String nameA = a.getNodeName();
						String nameB = b.getNodeName();
						if ("arg".equals(nameA)) {
							return 0;
						} else {
							int result = nameA.compareTo(nameB);
							if (result == 0) {
								Node idA = getIDAttribute(a);
								Node idB = getIDAttribute(b);
								if (idA == null || idB == null) return 0;
								return idA.getNodeValue().compareTo(idB.getNodeValue());
							}
							return result;
						}
					});
					if (count > 0) println();
					for (int i = 0; i < count; i++) {
						print(nodes.get(i), level + 1);
					}
					if (count > 0) {
						for (int i = 0; i < level; i++) print("\t");
					}
				}
				print("</");
				print(nodeName(node));
				print(">");
				println();
				break;
			}
		}
		out.flush();
	}

	Attr[] sort(NamedNodeMap attrs) {
		if (attrs == null)
			return new Attr[0];
		Attr result[] = new Attr[attrs.getLength()];
		for (int i = 0; i < result.length; i++) {
			result[i] = (Attr) attrs.item(i);
		}
		Arrays.sort(result, (arg0, arg1) -> nodeName(arg0).compareTo(nodeName(arg1)));
		return result;
	}

	String normalize(String s) {
		if (s == null) return "";
		StringBuffer str = new StringBuffer();
		for (int i = 0, length = s.length(); i < length; i++) {
			char ch = s.charAt(i);
			switch (ch) {
				case '"': str.append("\""); break;
				case '\r':
				case '\n':
					// FALL THROUGH
				default: str.append(ch);
			}
		}
		return str.toString();
	}
	
	public void setNodeFilter(String filter) {
		
		nodeFilter = filter;
	}
	
	public void setAttributeFilter(String[] filter) {
		attributeFilter = filter;
	}
	
	public void setIDAttributes(String[] ids) {
		idAttributes = ids;
	}
}