/*******************************************************************************
 * Copyright (c) 2003 - 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.io.IOException;
import java.io.Reader;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import javax.security.auth.login.LoginException;

import org.eclipse.mylyn.tasks.core.web.HtmlStreamTokenizer;
import org.eclipse.mylyn.tasks.core.web.HtmlTag;
import org.eclipse.mylyn.tasks.core.web.HtmlStreamTokenizer.Token;

/**
 * Parses Bugzilla keywords page to determine keywords valid in this
 * installation
 * 
 * @author Shawn Minto
 */
public class KeywordParser {
	/** Tokenizer used on the stream */
	private static HtmlStreamTokenizer tokenizer;

	/**
	 * Constructor.
	 * 
	 * @param in
	 *            The input stream for the keywords page.
	 */
	public KeywordParser(Reader in) {
		tokenizer = new HtmlStreamTokenizer(in, null);
	}

	public String getEncoding() {
		return "";
	}

	/**
	 * Parse the keyword page for the valid products that a bug can be logged
	 * for
	 * 
	 * @return A list of the keywordds that we can enter bugs for
	 * @throws IOException
	 * @throws ParseException
	 */
	public List<String> getKeywords() throws IOException, ParseException, LoginException {
		ArrayList<String> keywords = new ArrayList<String>();

		boolean isTitle = false;
		boolean possibleBadLogin = false;
		String title = "";

		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {

			// make sure that bugzilla doesn't want us to login
			if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.TITLE
					&& !((HtmlTag) (token.getValue())).isEndTag()) {
				isTitle = true;
				continue;
			}

			if (isTitle) {
				// get all of the data from inside of the title tag
				if (token.getType() != Token.TAG) {
					title += ((StringBuffer) token.getValue()).toString().toLowerCase() + " ";
					continue;
				} else if (token.getType() == Token.TAG
						&& ((HtmlTag) token.getValue()).getTagType() == HtmlTag.Type.TITLE
						&& ((HtmlTag) token.getValue()).isEndTag()) {
					// check if we may have a problem with login by looking at
					// the title of the page
					if ((title.indexOf("login") != -1
							|| (title.indexOf("invalid") != -1 && title.indexOf("password") != -1)
							|| title.indexOf("check e-mail") != -1 || title.indexOf("error") != -1))
						possibleBadLogin = true;
					isTitle = false;
					title = "";
				}
				continue;
			}

			if (token.getType() == Token.TAG) {
				HtmlTag tag = (HtmlTag) token.getValue();
				if (tag.getTagType() == HtmlTag.Type.TR && !tag.isEndTag()) {
					token = tokenizer.nextToken();
					if (token.getType() != Token.EOF && token.getType() == Token.TAG) {
						tag = (HtmlTag) token.getValue();
						if (tag.getTagType() != HtmlTag.Type.TH)
							continue;
						else {
							if (tag.getAttribute("align") == null
									|| !"left".equalsIgnoreCase(tag.getAttribute("align")))
								parseKeywords(keywords);

						}
					}
					continue;
				}
			}
		}

		// if we don't have any keywords and suspect that there was a login
		// problem, assume we had a login problem
		if (keywords == null && possibleBadLogin)
			throw new LoginException(IBugzillaConstants.MESSAGE_LOGIN_FAILURE);
		return keywords;
	}

	/**
	 * Parse the keywords that we can enter bugs for
	 * 
	 * @param keywords
	 *            The list of keywords to add this new product to
	 * @return
	 */
	private void parseKeywords(List<String> keywords) throws IOException, ParseException {
		StringBuffer sb = new StringBuffer();

		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
			if (token.getType() == Token.TAG) {
				HtmlTag tag = (HtmlTag) token.getValue();
				if (tag.getTagType() == HtmlTag.Type.TH
						&& (tag.isEndTag() || !"left".equalsIgnoreCase(tag.getAttribute("align"))))
					break;
			} else if (token.getType() == Token.TEXT)
				sb.append(token.toString());
		}

		String prod = HtmlStreamTokenizer.unescape(sb).toString();
		if (prod.endsWith(":"))
			prod = prod.substring(0, prod.length() - 1);
		keywords.add(prod);

		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
			if (token.getType() == Token.TAG) {
				HtmlTag tag = (HtmlTag) token.getValue();
				if (tag.getTagType() == HtmlTag.Type.TR && tag.isEndTag())
					break;

			}
		}
	}

}
