/*******************************************************************************
 * Copyright (c) 2004 - 2006 University Of British Columbia 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:
 *     University Of British Columbia - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.bugzilla.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Quick config rdf parser.
 * 
 * <pre>
 *     config.cgi?ctype=rdf
 * </pre>
 * 
 * Populates a <link>ProductConfiguration</link> data structure.
 * 
 * @author Rob Elves
 */
public class SaxConfigurationContentHandler extends DefaultHandler {

	private static final String ELEMENT_RESOLUTION = "resolution";

	private static final String ELEMENT_STATUS_OPEN = "status_open";

	private static final String ELEMENT_TARGET_MILESTONE = "target_milestone";

	private static final String ELEMENT_TARGET_MILESTONES = "target_milestones";

	private static final String ELEMENT_INSTALL_VERSION = "install_version";

	private static final String ATTRIBUTE_RDF_ABOUT = "rdf:about";

	private static final String ATTRIBUTE_RESOURCE = "resource";

	private static final String ELEMENT_VERSION = "version";

	private static final String ELEMENT_VERSIONS = "versions";

	private static final String ELEMENT_COMPONENT = "component";

	private static final String ELEMENT_COMPONENTS = "components";

	private static final String ELEMENT_NAME = "name";

	private static final String ELEMENT_PRODUCTS = "products";

	private static final String ELEMENT_SEVERITY = "severity";

	private static final String ELEMENT_PRIORITY = "priority";

	private static final String ELEMENT_KEYWORD = "keyword";

	private static final String ELEMENT_OP_SYS = "op_sys";

	private static final String ELEMENT_PLATFORM = "platform";

	private static final String ELEMENT_LI = "li";

	private static final String ELEMENT_STATUS = "status";

	private static final int EXPECTING_ROOT = 0;

	private static final int IN_INSTALL_VERSION = 1 << 1;

	private static final int IN_STATUS = 1 << 2;

	private static final int IN_PLATFORM = 1 << 3;

	private static final int IN_OP_SYS = 1 << 4;

	private static final int IN_PRIORITY = 1 << 5;

	private static final int IN_SEVERITY = 1 << 6;

	private static final int IN_PRODUCTS = 1 << 7;

	private static final int IN_COMPONENTS = 1 << 8;

	private static final int IN_VERSIONS = 1 << 9;

	private static final int IN_LI = 1 << 10;

	private static final int IN_LI_LI = 1 << 11;

	private static final int IN_NAME = 1 << 12;

	private static final int IN_COMPONENT = 1 << 13;

	private static final int IN_VERSION = 1 << 14;

	private static final int IN_TARGET_MILESTONES = 1 << 15;

	private static final int IN_TARGET_MILESTONE = 1 << 16;

	private static final int IN_STATUS_OPEN = 1 << 17;

	private static final int IN_RESOLUTION = 1 << 18;

	private static final int IN_KEYWORD = 1 << 19;

	private static final int IN_STATUS_CLOSED = 1 << 20;

	private int state = EXPECTING_ROOT;

	private StringBuffer currentProduct = new StringBuffer();

	private StringBuffer parsedValue = new StringBuffer();

	private String about;

	private RepositoryConfiguration configuration = new RepositoryConfiguration();

	private Map<String, List<String>> components = new HashMap<String, List<String>>();

	private Map<String, List<String>> versions = new HashMap<String, List<String>>();

	private Map<String, List<String>> milestones = new HashMap<String, List<String>>();

	private Map<String, StringBuffer> componentNames = new HashMap<String, StringBuffer>();

	private Map<String, StringBuffer> versionNames = new HashMap<String, StringBuffer>();

	private Map<String, StringBuffer> milestoneNames = new HashMap<String, StringBuffer>();

	public RepositoryConfiguration getConfiguration() {
		return configuration;
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		switch (state) {

		case IN_PRODUCTS | IN_LI | IN_NAME:
			currentProduct.append(String.copyValueOf(ch, start, length));
			break;
		case IN_COMPONENTS | IN_LI | IN_COMPONENT | IN_NAME:
			String comp = String.copyValueOf(ch, start, length);
			if (about != null) {
				StringBuffer name = componentNames.get(about);
				if (name == null) {
					name = new StringBuffer();
					componentNames.put(about, name);
				}
				name.append(comp);
			}
			break;
		case IN_VERSIONS | IN_LI | IN_VERSION | IN_NAME:
			String ver = String.copyValueOf(ch, start, length);
			if (about != null) {
				StringBuffer name = versionNames.get(about);
				if (name == null) {
					name = new StringBuffer();
					versionNames.put(about, name);
				}
				name.append(ver);
			}
			break;
		case IN_TARGET_MILESTONES | IN_LI | IN_TARGET_MILESTONE | IN_NAME:
			String target = String.copyValueOf(ch, start, length);
			if (about != null) {
				StringBuffer name = milestoneNames.get(about);
				if (name == null) {
					name = new StringBuffer();
					milestoneNames.put(about, name);
				}
				name.append(target);
			}
			break;
		case IN_PLATFORM | IN_LI:
			parsedValue.append(String.copyValueOf(ch, start, length));
			break;
		case IN_OP_SYS | IN_LI:
			parsedValue.append(String.copyValueOf(ch, start, length));
			break;
		case IN_PRIORITY | IN_LI:
			parsedValue.append(String.copyValueOf(ch, start, length));
			break;
		case IN_SEVERITY | IN_LI:
			parsedValue.append(String.copyValueOf(ch, start, length));
			break;
		case IN_INSTALL_VERSION:
			parsedValue.append(String.copyValueOf(ch, start, length));
			break;
		case IN_STATUS | IN_LI:
			parsedValue.append(String.copyValueOf(ch, start, length));
			break;
		case IN_RESOLUTION | IN_LI:
			parsedValue.append(String.copyValueOf(ch, start, length));
			break;
		case IN_KEYWORD | IN_LI:
			parsedValue.append(String.copyValueOf(ch, start, length));
			break;
		case IN_STATUS_OPEN | IN_LI:
			parsedValue.append(String.copyValueOf(ch, start, length));
			break;
		}
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

		if (localName.equals(ELEMENT_STATUS)) {
			state = state | IN_STATUS;
		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI) == IN_LI)) {
			state = state | IN_LI_LI;
			parseResource(attributes);
		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI) != IN_LI)) {
			state = state | IN_LI;
		} else if (localName.equals(ELEMENT_PLATFORM)) {
			state = state | IN_PLATFORM;
		} else if (localName.equals(ELEMENT_OP_SYS)) {
			state = state | IN_OP_SYS;
		} else if (localName.equals(ELEMENT_PRIORITY)) {
			state = state | IN_PRIORITY;
		} else if (localName.equals(ELEMENT_SEVERITY)) {
			state = state | IN_SEVERITY;
		} else if (localName.equals(ELEMENT_PRODUCTS)) {
			state = state | IN_PRODUCTS;
		} else if (localName.equals(ELEMENT_OP_SYS)) {
			state = state | IN_OP_SYS;
		} else if (localName.equals(ELEMENT_NAME)) {
			state = state | IN_NAME;
			currentProduct = new StringBuffer();
		} else if (localName.equals(ELEMENT_COMPONENTS)) {
			state = state | IN_COMPONENTS;
		} else if (localName.equals(ELEMENT_COMPONENT)) {
			state = state | IN_COMPONENT;
			parseResource(attributes);
		} else if (localName.equals(ELEMENT_VERSIONS)) {
			state = state | IN_VERSIONS;
		} else if (localName.equals(ELEMENT_VERSION)) {
			state = state | IN_VERSION;
			parseResource(attributes);
		} else if (localName.equals(ELEMENT_INSTALL_VERSION)) {
			state = state | IN_INSTALL_VERSION;
		} else if (localName.equals(ELEMENT_TARGET_MILESTONES)) {
			state = state | IN_TARGET_MILESTONES;
		} else if (localName.equals(ELEMENT_TARGET_MILESTONE)) {
			state = state | IN_TARGET_MILESTONE;
			parseResource(attributes);
		} else if (localName.equals(ELEMENT_STATUS_OPEN)) {
			state = state | IN_STATUS_OPEN;
		} else if (localName.equals(ELEMENT_RESOLUTION)) {
			state = state | IN_RESOLUTION;
		} else if (localName.equals(ELEMENT_KEYWORD)) {
			state = state | IN_KEYWORD;
		}
		parsedValue = new StringBuffer();
	}

	private void parseResource(Attributes attributes) {

		switch (state) {
		case IN_PRODUCTS | IN_LI | IN_COMPONENTS | IN_LI_LI:
			if (attributes != null) {
				String compURI = attributes.getValue(ATTRIBUTE_RESOURCE);
				if (compURI != null && currentProduct.length() > 0) {
					List<String> compURIs = components.get(currentProduct.toString());
					if (compURIs == null) {
						compURIs = new ArrayList<String>();
						components.put(currentProduct.toString(), compURIs);
					}
					compURIs.add(compURI);
				}
			}
			break;
		case IN_PRODUCTS | IN_LI | IN_VERSIONS | IN_LI_LI:
			if (attributes != null) {
				String resourceURI = attributes.getValue(ATTRIBUTE_RESOURCE);
				if (resourceURI != null && currentProduct.length() > 0) {
					List<String> versionUris = versions.get(currentProduct.toString());
					if (versionUris == null) {
						versionUris = new ArrayList<String>();
						versions.put(currentProduct.toString(), versionUris);
					}
					versionUris.add(resourceURI);
				}
			}
			break;
		case IN_PRODUCTS | IN_LI | IN_TARGET_MILESTONES | IN_LI_LI:
			if (attributes != null) {
				String resourceURI = attributes.getValue(ATTRIBUTE_RESOURCE);
				if (resourceURI != null) {
					List<String> milestoneUris = milestones.get(currentProduct.toString());
					if (milestoneUris == null) {
						milestoneUris = new ArrayList<String>();
						milestones.put(currentProduct.toString(), milestoneUris);
					}
					milestoneUris.add(resourceURI);
				}
			}
			break;
		case IN_COMPONENTS | IN_LI | IN_COMPONENT:
			if (attributes != null) {
				about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
			}
			break;
		case IN_VERSIONS | IN_LI | IN_VERSION:
			if (attributes != null) {
				about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
			}
			break;

		case IN_TARGET_MILESTONES | IN_LI | IN_TARGET_MILESTONE:
			if (attributes != null) {
				about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
			}
			break;

		}
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {

		// KEEP: && ((state & IN_LI) == IN_LI)

		if (localName.equals(ELEMENT_STATUS)) {
			state = state & ~IN_STATUS;
		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI_LI) == IN_LI_LI)) {
			state = state & ~IN_LI_LI;
		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI_LI) != IN_LI_LI)) {
			state = state & ~IN_LI;
			if (parsedValue.length() == 0)
				return;
			if (state == (IN_STATUS)) {
				configuration.addStatus(parsedValue.toString());
			} else if (state == (IN_STATUS_OPEN)) {
				configuration.addOpenStatusValue(parsedValue.toString());
			} else if (state == (IN_STATUS_CLOSED)) {
				// TODO: Add closed status values to configuration
			} else if (state == (IN_RESOLUTION)) {
				configuration.addResolution(parsedValue.toString());
			} else if (state == (IN_KEYWORD)) {
				configuration.addKeyword(parsedValue.toString());
			} else if (state == (IN_PLATFORM)) {
				configuration.addPlatform(parsedValue.toString());
			} else if (state == (IN_OP_SYS)) {
				configuration.addOS(parsedValue.toString());
			} else if (state == (IN_PRIORITY)) {
				configuration.addPriority(parsedValue.toString());
			} else if (state == (IN_SEVERITY)) {
				configuration.addSeverity(parsedValue.toString());
			}
		} else if (localName.equals(ELEMENT_PLATFORM)) {
			state = state & ~IN_PLATFORM;
		} else if (localName.equals(ELEMENT_OP_SYS)) {
			state = state & ~IN_OP_SYS;
		} else if (localName.equals(ELEMENT_PRIORITY)) {
			state = state & ~IN_PRIORITY;
		} else if (localName.equals(ELEMENT_SEVERITY)) {
			state = state & ~IN_SEVERITY;
		} else if (localName.equals(ELEMENT_PRODUCTS)) {
			state = state & ~IN_PRODUCTS;
		} else if (localName.equals(ELEMENT_OP_SYS)) {
			state = state & ~IN_OP_SYS;
		} else if (localName.equals(ELEMENT_NAME)) {
			state = state & ~IN_NAME;
			if (state == (IN_PRODUCTS | IN_LI) && currentProduct.length() > 0) {
				configuration.addProduct(currentProduct.toString());
			}
		} else if (localName.equals(ELEMENT_COMPONENTS)) {
			state = state & ~IN_COMPONENTS;
		} else if (localName.equals(ELEMENT_COMPONENT)) {
			state = state & ~IN_COMPONENT;
		} else if (localName.equals(ELEMENT_VERSION)) {
			state = state & ~IN_VERSION;
		} else if (localName.equals(ELEMENT_VERSIONS)) {
			state = state & ~IN_VERSIONS;
		} else if (localName.equals(ELEMENT_INSTALL_VERSION)) {
			state = state & ~IN_INSTALL_VERSION;
			configuration.setInstallVersion(parsedValue.toString());
		} else if (localName.equals(ELEMENT_TARGET_MILESTONE)) {
			state = state & ~IN_TARGET_MILESTONE;
		} else if (localName.equals(ELEMENT_TARGET_MILESTONES)) {
			state = state & ~IN_TARGET_MILESTONES;
		} else if (localName.equals(ELEMENT_STATUS_OPEN)) {
			state = state & ~IN_STATUS_OPEN;
		} else if (localName.equals(ELEMENT_RESOLUTION)) {
			state = state & ~IN_RESOLUTION;
		} else if (localName.equals(ELEMENT_KEYWORD)) {
			state = state & ~IN_KEYWORD;
		}
	}

	@Override
	public void endDocument() throws SAXException {

		for (String product : components.keySet()) {
			List<String> componentURIs = components.get(product);
			for (String uri : componentURIs) {
				StringBuffer realName = componentNames.get(uri);
				if (realName != null && product.length() > 0) {
					configuration.addComponent(product, realName.toString());
				}
			}
		}

		for (String product : versions.keySet()) {
			List<String> versionURIs = versions.get(product);
			for (String uri : versionURIs) {
				StringBuffer realName = versionNames.get(uri);
				if (realName != null) {
					configuration.addVersion(product, realName.toString());
				}
			}

		}

		for (String product : milestones.keySet()) {
			List<String> milestoneURIs = milestones.get(product);
			for (String uri : milestoneURIs) {
				StringBuffer realName = milestoneNames.get(uri);
				if (realName != null) {
					configuration.addTargetMilestone(product, realName.toString());
				}
			}

		}
		super.endDocument();
	}
}
