/*******************************************************************************
 * 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.search;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.ArrayList;

import javax.security.auth.login.LoginException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
import org.eclipse.mylyn.internal.bugzilla.core.internal.HtmlStreamTokenizer;
import org.eclipse.mylyn.internal.bugzilla.core.internal.HtmlTag;
import org.eclipse.mylyn.internal.bugzilla.core.internal.HtmlStreamTokenizer.Token;
import org.eclipse.mylyn.provisional.tasklist.TaskRepository;

/**
 * Class to parse the update data from the server
 * 
 * author: kvesik
 * 
 * created on: Feb 25, 2003
 * 
 */
public class BugzillaQueryPageParser {
	
	private static final String POST_ARGS_PASSWORD = "&Bugzilla_password=";

	private static final String POST_ARGS_LOGIN_FIRST = "&GoAheadAndLogIn=1&Bugzilla_login=";

	/** The name of the bugzilla server */
	private String urlString;

	/** The input stream */
	private BufferedReader in = null;

	/** True if the operation was successful */
	private boolean successful;

	/** Exception to be displayed if there was an error */
	private Exception exception;

	/** The progress monitor for the update */
	private IProgressMonitor monitor;

	/** Selection lists as ArrayLists */
	private ArrayList<String> statusValues = new ArrayList<String>();

	private ArrayList<String> preselectedStatusValues = new ArrayList<String>();

	private ArrayList<String> resolutionValues = new ArrayList<String>();

	private ArrayList<String> severityValues = new ArrayList<String>();

	private ArrayList<String> priorityValues = new ArrayList<String>();

	private ArrayList<String> hardwareValues = new ArrayList<String>();

	private ArrayList<String> osValues = new ArrayList<String>();

	private ArrayList<String> productValues = new ArrayList<String>();

	private ArrayList<String> componentValues = new ArrayList<String>();

	private ArrayList<String> versionValues = new ArrayList<String>();

	private ArrayList<String> targetValues = new ArrayList<String>();

	public BugzillaQueryPageParser(TaskRepository repository, IProgressMonitor monitor) throws LoginException, IOException {
		this.monitor = monitor;

		// get the servers url
		urlString = repository.getUrl() + "/query.cgi";

		// if we are dealing with 2.18 or higher we need to use the folowing in the
		// query string to get the right search page
		// UPDATE: There doesn't appear to be any harm in appending this to 2.18, 2.20, 2.20.1 and without it we
		// don't get the advanced view so 2.20 and 2.20.1 break
		//if (repository.getVersion().equals(BugzillaServerVersion.SERVER_218.toString())) {
			urlString += "?format=advanced";
		//}

		// use the user name and password if we have it
		if (repository.hasCredentials()) {
			try {
				// if we are dealing with 2.18 we already have the ? from before
				// so we need
				// an & instead. If other version, still add ?
				// if (repository.getVersion().equals(BugzillaServerVersion.SERVER_218.toString()))
				//	urlString += "&";
				// else
				// urlString += "?";

				urlString += POST_ARGS_LOGIN_FIRST
						+ URLEncoder.encode(repository.getUserName(), BugzillaPlugin.ENCODING_UTF_8)
						+ POST_ARGS_PASSWORD
						+ URLEncoder.encode(repository.getPassword(), BugzillaPlugin.ENCODING_UTF_8);
			} catch (UnsupportedEncodingException e) {
				/*
				 * Do nothing. Every implementation of the Java platform is
				 * required to support the standard charset
				 * BugzillaPlugin.ENCODING_UTF_8
				 */
			}
		}

		successful = false;

		// try to get the new options from the page
		parseDocument();
		if (!successful) {
			if (exception instanceof MalformedURLException) {
				MessageDialog
						.openError(
								null,
								"Unsupported Protocol",
								"The server that was specified for Bugzilla is not supported by your JVM.\nPlease make sure that you are using a JDK that supports SSL.");
			} else {
//				throw exception
				// if there was a problem with the operation, display an error
				// message
				ErrorDialog.openError(null, IBugzillaConstants.TITLE_MESSAGE_DIALOG, "Bugzilla could not complete the the update.",
						new Status(IStatus.ERROR, IBugzillaConstants.PLUGIN_ID, IStatus.OK, "url may be invalid",
								exception));
			}
		}
	}

	/**
	 * Get whether the update was successful
	 * 
	 * @return <code>true</code> if the update was successful
	 */
	public boolean wasSuccessful() {
		return successful;
	}

	/**
	 * Parse the data from the server for the query options
	 * @throws IOException 
	 */
	private void parseDocument() throws LoginException, IOException {
		try {
			// if the operation has been cancelled already, return
			if (monitor.isCanceled()) {
				monitor.done();
				return;
			}

			// try to connect to the server
			monitor.subTask("Connecting to server");

			URL url = new URL(this.urlString);
			URLConnection cntx = BugzillaPlugin.getDefault().getUrlConnection(url);

			if (cntx != null) {
				InputStream input = cntx.getInputStream();
				if (input != null) {

					monitor.worked(1);

					// initialize the input stream
					in = new BufferedReader(new InputStreamReader(input));

					// increment the position of the status monitor
					monitor.worked(2);

					// check if the operation has been cancelled so we can end
					// if it has been
					if (monitor.isCanceled())
						monitor.done();
					else
						monitor.subTask("Reading values from server");

					// parse the data from the server
					parseQueryPage(in);

					// set the operation to being successful
					successful = true;
				}
			}

		} catch (LoginException e) {
			throw e;
		} catch (IOException e) {
			throw e;
		} catch (Exception e) {
			// if we can't connect, log the problem and save the exception to
			// handle later
			monitor.done();
			exception = e;
			BugzillaPlugin.log(new Status(IStatus.ERROR, IBugzillaConstants.PLUGIN_ID, IStatus.OK,
					"Failed to create URL and open input stream: " + urlString, e));
			return;
		} finally {
			try {
				if (in != null)
					in.close();
			} catch (IOException exitAnyway) {
				in = null;
			}
		}
	}

	/**
	 * Check if all of the lists of options are empty
	 * 
	 * @return true if all of the options lists are empty
	 */
	private boolean allListsEmpty() {
		return statusValues.isEmpty() && preselectedStatusValues.isEmpty() && resolutionValues.isEmpty()
				&& severityValues.isEmpty() && priorityValues.isEmpty() && hardwareValues.isEmpty()
				&& osValues.isEmpty() && productValues.isEmpty() && componentValues.isEmpty()
				&& versionValues.isEmpty() && targetValues.isEmpty();
	}

	/**
	 * Get the new status values
	 * 
	 * @return An array of the new status values
	 */
	public String[] getStatusValues() {
		String[] array = new String[statusValues.size()];

		// create the array and return it
		for (int i = 0; i < statusValues.size(); i++)
			array[i] = statusValues.get(i);
		return array;
	}

	/**
	 * Get the new preselected status values
	 * 
	 * @return An array of the new preselected status values
	 */
	public String[] getPreselectedStatusValues() {
		String[] array = new String[preselectedStatusValues.size()];

		// create the array and return it
		for (int i = 0; i < preselectedStatusValues.size(); i++)
			array[i] = preselectedStatusValues.get(i);
		return array;
	}

	/**
	 * Get the new resolution values
	 * 
	 * @return An array of the new resolution values
	 */
	public String[] getResolutionValues() {
		String[] array = new String[resolutionValues.size()];

		// create the array and return it
		for (int i = 0; i < resolutionValues.size(); i++)
			array[i] = resolutionValues.get(i);
		return array;
	}

	/**
	 * Get the new severity values
	 * 
	 * @return An array of the new severity values
	 */
	public String[] getSeverityValues() {
		String[] array = new String[severityValues.size()];

		// create the array and return it
		for (int i = 0; i < severityValues.size(); i++)
			array[i] = severityValues.get(i);
		return array;
	}

	/**
	 * Get the new priority values
	 * 
	 * @return An array of the new priority values
	 */
	public String[] getPriorityValues() {
		String[] array = new String[priorityValues.size()];

		// create the array and return it
		for (int i = 0; i < priorityValues.size(); i++)
			array[i] = priorityValues.get(i);
		return array;
	}

	/**
	 * Get the new hardware values
	 * 
	 * @return An array of the new hardware values
	 */
	public String[] getHardwareValues() {
		String[] array = new String[hardwareValues.size()];

		// create the array and return it
		for (int i = 0; i < hardwareValues.size(); i++)
			array[i] = hardwareValues.get(i);
		return array;
	}

	/**
	 * Get the new OS values
	 * 
	 * @return An array of the new OS values
	 */
	public String[] getOSValues() {
		String[] array = new String[osValues.size()];

		// create the array and return it
		for (int i = 0; i < osValues.size(); i++)
			array[i] = osValues.get(i);
		return array;
	}

	/**
	 * Get the new product values
	 * 
	 * @return An array of the new product values
	 */
	public String[] getProductValues() {
		String[] array = new String[productValues.size()];

		// create the array and return it
		for (int i = 0; i < productValues.size(); i++)
			array[i] = productValues.get(i);
		return array;
	}

	/**
	 * Get the new component values
	 * 
	 * @return An array of the new component values
	 */
	public String[] getComponentValues() {
		String[] array = new String[componentValues.size()];

		// create the array and return it
		for (int i = 0; i < componentValues.size(); i++)
			array[i] = componentValues.get(i);
		return array;
	}

	/**
	 * Get the new version values
	 * 
	 * @return An array of the new version values
	 */
	public String[] getVersionValues() {
		String[] array = new String[versionValues.size()];

		// create the array and return it
		for (int i = 0; i < versionValues.size(); i++)
			array[i] = versionValues.get(i);
		return array;
	}

	/**
	 * Get the new milestone values
	 * 
	 * @return An array of the new milestone values
	 */
	public String[] getTargetValues() {
		String[] array = new String[targetValues.size()];

		// create the array and return it
		for (int i = 0; i < targetValues.size(); i++)
			array[i] = targetValues.get(i);
		return array;
	}

	/**
	 * Parse the bugzilla query.cgi page for some seach options
	 * 
	 * @param inputReader
	 *            The input stream for the page
	 * @throws LoginException
	 * @throws ParseException
	 * @throws IOException
	 */
	private void parseQueryPage(Reader inputReader) throws LoginException, ParseException, IOException {
		HtmlStreamTokenizer tokenizer = new HtmlStreamTokenizer(inputReader, null);

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

		for (HtmlStreamTokenizer.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 in the title tag to compare with
				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 the title looks like we may have a problem with
					// login
					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;
			}

			// we have found the start of attribute values
			if (token.getType() == Token.TAG) {
				HtmlTag tag = (HtmlTag) token.getValue();
				if (tag.getTagType() == HtmlTag.Type.TD && "left".equalsIgnoreCase(tag.getAttribute("align"))) {
					// parse the attribute values
					parseAttributeValue(tokenizer);
					continue;
				}
			}
		}

		// if all of the lists are empty and we suspect bad login info, assume
		// that it was a bad login
		if (possibleBadLogin && allListsEmpty())
			throw new LoginException(IBugzillaConstants.MESSAGE_LOGIN_FAILURE);
	}

	/**
	 * Parse the case where the attribute value is an option
	 * 
	 * @param parameterName
	 *            The name of the attribute value
	 * @param tokenizer
	 *            The tokenizer to get data from the stream
	 * @throws IOException
	 * @throws ParseException
	 */
	private void parseSelect(String parameterName, HtmlStreamTokenizer tokenizer) throws IOException, ParseException {

		HtmlStreamTokenizer.Token token = tokenizer.nextToken();
		while (token.getType() != Token.EOF) {
			if (token.getType() == Token.TAG) {
				HtmlTag tag = (HtmlTag) token.getValue();
				if (tag.getTagType() == HtmlTag.Type.SELECT && tag.isEndTag())
					break;
				if (tag.getTagType() == HtmlTag.Type.OPTION && !tag.isEndTag()) {
					String optionName = tag.getAttribute("value");
					boolean selected = tag.hasAttribute("selected");
					StringBuffer optionText = new StringBuffer();
					for (token = tokenizer.nextToken(); token.getType() == Token.TEXT; token = tokenizer.nextToken()) {
						if (optionText.length() > 0) {
							optionText.append(' ');
						}
						optionText.append((StringBuffer) token.getValue());
					}
					// add the value to the appropriate list of attributes
					if (parameterName.equals("bug_status")) {
						statusValues.add(optionName);

						// check if the status is to be preselected or not
						if (selected)
							preselectedStatusValues.add(optionName);
					} else if (parameterName.equals("resolution"))
						resolutionValues.add(optionName);
					else if (parameterName.equals("bug_severity"))
						severityValues.add(optionName);
					else if (parameterName.equals("priority"))
						priorityValues.add(optionName);
					else if (parameterName.equals("rep_platform"))
						hardwareValues.add(optionName);
					else if (parameterName.equals("op_sys"))
						osValues.add(optionName);
					else if (parameterName.equals("product"))
						productValues.add(optionName);
					else if (parameterName.equals("component"))
						componentValues.add(optionName);
					else if (parameterName.equals("version"))
						versionValues.add(optionName);
					else if (parameterName.equals("target_milestone"))
						targetValues.add(optionName);
				} else {
					token = tokenizer.nextToken();
				}
			} else {
				token = tokenizer.nextToken();
			}
		}
	}

	/**
	 * Parse the case where we think we found an attribute value
	 * 
	 * @param tokenizer
	 *            The tokenizer to get the data from the stream
	 * @throws IOException
	 * @throws ParseException
	 */
	private void parseAttributeValue(HtmlStreamTokenizer tokenizer) throws IOException, ParseException {

		HtmlStreamTokenizer.Token token = tokenizer.nextToken();
		if (token.getType() == Token.TAG) {
			HtmlTag tag = (HtmlTag) token.getValue();
			if (tag.getTagType() == HtmlTag.Type.SELECT && !tag.isEndTag()) {
				String parameterName = tag.getAttribute("name");
				parseSelect(parameterName, tokenizer);
			} else if (tag.getTagType() == HtmlTag.Type.LABEL && !tag.isEndTag()) {
				parseAttributeValue(tokenizer);
			}
		}
	}
}
