/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.meta.internal;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;

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

import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.jsf.common.ui.internal.utils.ResourceUtils;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.meta.AttributeDescriptor;
import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * Used by Sybase CMConfig model loader
 * @author mengbo
 * @deprecated
 */
public class ElementDescReader {
	private static Logger _log = PDPlugin.getLogger(ElementDescReader.class);

	private Map _definedCategoryMap = new HashMap();

	private Map _definedAttributeMap = new HashMap();

	private URL _url;

	private String[] _optimizedLocales = null;

	/**
	 * @param url
	 */
	public ElementDescReader(URL url) {
		this._url = url;
	}

	/**
	 * Read xml information and fill the map
	 * 
	 * @param map
	 * @throws ParserConfigurationException
	 * @throws FactoryConfigurationError
	 * @throws SAXException
	 * @throws IOException
	 */
	public void readElements(Map map) throws ParserConfigurationException,
			FactoryConfigurationError, SAXException, IOException {
		DocumentBuilder builder = DocumentBuilderFactory.newInstance()
				.newDocumentBuilder();
		
		InputStream stream = null; 
		Document doc = null;
		try
		{
			stream = this._url.openStream();
			doc = builder.parse(stream);
		}
		finally
		{
			ResourceUtils.ensureClosed(stream);
		}

		Element taglib = doc.getDocumentElement();
		String nameSpace = taglib.getAttribute("uri");

		NodeList list = doc.getElementsByTagName("tag");
		if (list != null && list.getLength() != 0) {
			int size = list.getLength();
			for (int i = 0; i < size; i++) {
				Element tag = (Element) list.item(i);
				ElementDescriptor desc = new ElementDescriptor();
				desc.setTagName(tag.getAttribute("name"));
				desc.setNamespaceURI(nameSpace);

				// support for help context id.
				desc.setHelpContextID(tag.getAttribute("helpContextId"));

				NodeList children = tag.getChildNodes();
				// first calculate category and refered category quantity
				NodeList cateNodes = tag.getElementsByTagName("category");
				NodeList referedCateNodes = tag
						.getElementsByTagName("referedcategory");
				int cateNum = 0;
				if (cateNodes != null) {
					cateNum += cateNodes.getLength();
				}
				if (referedCateNodes != null) {
					cateNum += referedCateNodes.getLength();
				}

				if (cateNum > 0) {
					int length = children.getLength();
					String[] cates = new String[cateNum];
					List attrList = new ArrayList();
					int realCate = 0;
					for (int j = 0; j < length; j++) {
						Node node = children.item(j);
						if (node.getNodeType() == Node.ELEMENT_NODE) {
							Element element = (Element) node;
							String tagName = element.getTagName();
							if ("category".equals(tagName)
									|| "referedcategory".equals(tagName)) {
								String categoryName = element
										.getAttribute("name");
								if (categoryName != null
										&& !"".equals(categoryName)) {
									cates[realCate++] = categoryName;
									parseCategory(element, element, attrList);
								} else {
									Element definedCategory = handleReference(
											doc, element, true);
									String labelKey = definedCategory
											.getAttribute("displaylabel");
									if (labelKey != null
											&& !"".equals(labelKey)) {
										cates[realCate++] = getValue(labelKey);
									} else {
										cates[realCate++] = calculateDisplayLabel(definedCategory);
									}

									parseCategory(element, definedCategory,
											attrList);
								}
							}
						}

					}

					// for sort categories
					for (int m = 0, len = cates.length; m < len; m++) {
						for (int j = m + 1; j < len; j++) {
							CategoryNameComparator.addPair(cates[m], cates[j]);
						}
					}
					desc.setAttributeDescriptors(attrList);
				}

				map.put(desc.getTagName(), desc);
			}
		}
	}

	private String calculateDisplayLabel(Element definedElement) {
		String label = definedElement.getAttribute("displaylabel");
		return getValue(label);
	}

	private void parseCategory(Element category, Element definedCategory,
			List attrList) {
		String cateLabel = calculateDisplayLabel(definedCategory);
		// if the category is a referedcategory tag
		if (category != definedCategory) {
			String labelKey = category.getAttribute("displaylabel");
			if (labelKey != null && !"".equals(labelKey)) {
				cateLabel = getValue(labelKey);
			}
		}
		handleAttributes(definedCategory, cateLabel, attrList);
		if (category == definedCategory) {
			return;
		}

		// the category should be a referedcategory tag
		// include/add more attributes to category
		NodeList includes = category.getElementsByTagName("includeattrs");
		if (includes != null && includes.getLength() != 0) {
			Element includeAttrsTag = (Element) includes.item(0);
			handleAttributes(includeAttrsTag, cateLabel, attrList);

			// handle attribute override
			HashMap tempMap = new HashMap();
			Iterator itor = attrList.iterator();
			while (itor.hasNext()) {
				AttributeDescriptor adp = (AttributeDescriptor) itor.next();
				tempMap.put(adp.getAttributeName(), adp);
			}
			int listSize = attrList.size();
			int mapSize = tempMap.size();
			if (listSize != mapSize) {
				attrList.clear();
				Set set = tempMap.keySet();
				Iterator setor = set.iterator();
				while (setor.hasNext()) {
					String atName = (String) setor.next();
					AttributeDescriptor ad = (AttributeDescriptor) tempMap
							.get(atName);
					attrList.add(ad);
				}
			}

		}

		// exclude attributes from category
		NodeList excludes = category.getElementsByTagName("excludeattrs");
		if (excludes != null && excludes.getLength() != 0) {
			String displayNames = ((Element) excludes.item(0))
					.getAttribute("refs");
			StringTokenizer tokenizer = new StringTokenizer(displayNames, ", ");

			while (tokenizer.hasMoreTokens()) {
				String name = tokenizer.nextToken();
				Iterator itr = attrList.iterator();
				while (itr.hasNext()) {
					IAttributeDescriptor atr = (IAttributeDescriptor) itr
							.next();
					String atrName = atr.getAttributeName();
					if (name.equals(atrName)) {
						attrList.remove(atr);
						break;
					}
				}
			}
		}
	}

	/**
	 * handle all attribute element and referedattribute element under the root
	 * element
	 * 
	 * @param root
	 * @param cateLabel
	 * @param list
	 */
	private void handleAttributes(Element root, String cateLabel, List attrList) {
		NodeList allNodes = root.getChildNodes();
		NodeList attrNodes = root.getElementsByTagName("attribute");
		NodeList referedattrNodes = root
				.getElementsByTagName("referedattribute");
		int attrNum = 0;
		if (attrNodes != null) {
			attrNum += attrNodes.getLength();
		}
		if (referedattrNodes != null) {
			attrNum += referedattrNodes.getLength();
		}

		if (attrNum > 0) {
			int incAttrLength = allNodes.getLength();
			for (int i = 0; i < incAttrLength; i++) {
				Node node = allNodes.item(i);
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					Element incAttr = (Element) node;
					String tagName = incAttr.getTagName();
					if ("attribute".equals(tagName)
							|| "referedattribute".equals(tagName)) {
						String incAtrName = incAttr.getAttribute("name");
						Element refAttr = incAttr;
						if (incAtrName == null || "".equals(incAtrName)) {
							incAttr = handleReference(root.getOwnerDocument(),
									incAttr, false);
						}
						AttributeDescriptor attrDesc = parseAttribute(
								cateLabel, incAttr);
						String overrideName = refAttr
								.getAttribute("overridename");
						if (overrideName != null
								&& !"".equalsIgnoreCase(overrideName)) {
							attrDesc.setAttributeName(overrideName);
						}
						String ovDisplayLabel = refAttr
								.getAttribute("displaylabel");
						if (ovDisplayLabel != null
								&& !"".equalsIgnoreCase(ovDisplayLabel)) {
							attrDesc.setLabelString(getValue(ovDisplayLabel));
						}
						attrList.add(attrDesc);
					}

				}

			}
		}
	}

	private Element handleReference(Document doc, Element refElment,
			boolean isCategory) {
		String refName = refElment.getAttribute("ref");
		if (isCategory) {
			if (_definedCategoryMap.get(refName) != null) {
				Element definedCategory = (Element) _definedCategoryMap
						.get(refName);
				return definedCategory;
			}
		} else {
			if (_definedAttributeMap.get(refName) != null) {
				Element definedAttribute = (Element) _definedAttributeMap
						.get(refName);
				return definedAttribute;
			}
		}

		NodeList catgs = null;
		if (isCategory) {
			NodeList defineCates = doc.getElementsByTagName("categories");
			Element firstCate = (Element) defineCates.item(0);
			catgs = firstCate.getElementsByTagName("category");
		} else {
			NodeList defineCates = doc.getElementsByTagName("attributes");
			Element firstCate = (Element) defineCates.item(0);
			catgs = firstCate.getElementsByTagName("attribute");
		}
		int cateLen = catgs.getLength();
		Element definedElement = null;
		for (int n = 0; n < cateLen; n++) {
			String cateName = ((Element) catgs.item(n)).getAttribute("name");
			if (refName.equals(cateName) && !"".equals(refName)) {
				definedElement = (Element) catgs.item(n);
				break;
			}
		}
		if (isCategory) {
			_definedCategoryMap.put(refName, definedElement);
		} else {
			_definedAttributeMap.put(refName, definedElement);
		}
		return definedElement;
	}

	private AttributeDescriptor parseAttribute(String categoryName,
			Element attribute) {
		AttributeDescriptor attrDesc = new AttributeDescriptor();
		attrDesc.setCategory(categoryName);

		attrDesc.setAttributeName(attribute.getAttribute("name"));
		attrDesc.setDescription(attribute.getAttribute("description"));
		attrDesc.setValueType(attribute.getAttribute("type"));
		attrDesc.setRequired(attribute.hasAttribute("required"));
		attrDesc.setTypeParameter(attribute.getAttribute("typeparam"));
		String labelKey = attribute.getAttribute("displaylabel");
		attrDesc.setLabelString(getValue(labelKey));

		NodeList optionNodes = attribute.getElementsByTagName("option");
		if (optionNodes != null && optionNodes.getLength() != 0) {
			HashMap optionMap = new HashMap();
			int opLength = optionNodes.getLength();
			String defaultValue = null;
			for (int m = 0; m < opLength; m++) {
				Element optNode = (Element) optionNodes.item(m);
				String key = optNode.getAttribute("key");
				String value = optNode.getAttribute("value");
				if (value == null || value.length() == 0) {
					value = key;
				}
				if (optNode.hasAttribute("default")) {
					defaultValue = value;
				}
				optionMap.put(key, value);
			}
			attrDesc.setOptions(optionMap, defaultValue);
		}

		return attrDesc;
	}

	private String getValue(String key) {
		if (key != null && key.startsWith("%")) {
			String cmStr = this._url.toString();
			String propBaseStr = cmStr.substring(0, cmStr.lastIndexOf("."));

			String[] localeOptions = LocaleFallback.fallBack(Locale
					.getDefault());
			String[] options = localeOptions;
			if (_optimizedLocales != null) {
				options = _optimizedLocales;
			}
			for (int i = 0, size = options.length; i < size; i++) {
				StringBuffer sb = new StringBuffer();
				sb.append(propBaseStr);
				sb.append(options[i]);
				sb.append(".properties");
				String str = sb.toString();

				ResourceBundle rb = null;
				try {
					URL propUrl = new URL(str);
					rb = new PropertyResourceBundle(propUrl.openStream());
				} catch (Exception e1) {
					// we don't handle the exception here,since it is in a
					// fallback route,it is possible of not exist
					// _log.info("Info.ElementDescReader.ReadPropertyFile",
					// str);
					continue;
				}
				if (_optimizedLocales == null) {
					setOptimizedLocales(localeOptions, i);
				}

				String rbKey = key.substring(1);
				String value = null;
				try {
					value = rb.getString(rbKey);
				} catch (Exception e) {
					_log.info("Info.ElementDescReader.ReadPropertyFile.Key",
							rbKey, str, null);
					continue;
				}

				if (value != null) {
					return value;
				}

			}
			return null;
		}
		return key;
	}

	private void setOptimizedLocales(String[] originalLocales, int startPoint) {
		int size = originalLocales.length - startPoint;
		_optimizedLocales = new String[size];
		for (int i = 0; i < size; i++) {
			_optimizedLocales[i] = originalLocales[i + startPoint];
		}
	}
}
