/****************************************************************************
 * Copyright (c) 2007, 2008 Remy Suen and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *    Remy Suen <remy.suen@gmail.com> - initial API and implementation
 *    Markus Kuppe <mkuppe@versant.com> - bug 184036
 *    Nick Boldt <codeslave@ca.ibm.com> - bug 206528, 209410
 *    Dominik Goepel <dominik.goepel@gmx.de> - bug 216644
 *
 * SPDX-License-Identifier: EPL-2.0
 *****************************************************************************/
package org.eclipse.ecf.internal.presence.bot.kosmos;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDCreateException;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.presence.IIMMessageEvent;
import org.eclipse.ecf.presence.IIMMessageListener;
import org.eclipse.ecf.presence.bot.IChatRoomBotEntry;
import org.eclipse.ecf.presence.bot.IChatRoomMessageHandler;
import org.eclipse.ecf.presence.chatroom.IChatRoomContainer;
import org.eclipse.ecf.presence.chatroom.IChatRoomMessage;
import org.eclipse.ecf.presence.chatroom.IChatRoomMessageSender;
import org.eclipse.ecf.presence.im.IChatID;
import org.eclipse.ecf.presence.im.IChatMessageEvent;
import org.eclipse.ecf.presence.im.IChatMessageSender;
import org.eclipse.osgi.util.NLS;

public class ChatRoomMessageHandler implements IChatRoomMessageHandler {

	private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$

	private static final String LICENSE = "###############################################################################" //$NON-NLS-1$
			+ NEWLINE
			+ "# Copyright (c) 2007, 2008 Remy Suen and others." //$NON-NLS-1$
			+ NEWLINE
			+ "# This program and the accompanying materials are made" //$NON-NLS-1$
			+ NEWLINE
			+ "# available under the terms of the Eclipse Public License 2.0" //$NON-NLS-1$
			+ NEWLINE
			+ "# which is available at https://www.eclipse.org/legal/epl-2.0/" //$NON-NLS-1$
			+ NEWLINE
			+ "#" //$NON-NLS-1$
			+ NEWLINE
			+ "# Contributors:" //$NON-NLS-1$
			+ NEWLINE
			+ "#    Remy Suen <remy.suen@gmail.com> - initial API and implementation" //$NON-NLS-1$
			+ NEWLINE
			+ "#    Markus Kuppe <mkuppe@versant.com> - bug 184036" //$NON-NLS-1$
			+ NEWLINE
			+" *    Nick Boldt <codeslave@ca.ibm.com> - bug 206528, 209410" //$NON-NLS-1$
			+ NEWLINE
			+" *    Dominik Goepel <dominik.goepel@gmx.de> - bug 216644" //$NON-NLS-1$
			+ NEWLINE
			+" *    Nitin Dahyabhai <nitind@us.ibm.com> - bug 308908"
			+ NEWLINE
			+ "################################################################################"; //$NON-NLS-1$

	private static final String BUG_DATABASE_PREFIX = "https://bugs.eclipse.org/bugs/show_bug.cgi?id="; //$NON-NLS-1$
	private static final String BUG_DATABASE_POSTFIX = "&ctype=xml"; //$NON-NLS-1$

	private static final String SHORT_DESC_OPEN_TAG = "<short_desc>"; //$NON-NLS-1$
	private static final String SHORT_DESC_CLOSE_TAG = "</short_desc>"; //$NON-NLS-1$

	private static final String PRODUCT_OPEN_TAG = "<product>"; //$NON-NLS-1$
	private static final String PRODUCT_CLOSE_TAG = "</product>"; //$NON-NLS-1$

	private static final String COMPONENT_OPEN_TAG = "<component>"; //$NON-NLS-1$
	private static final String COMPONENT_CLOSE_TAG = "</component>"; //$NON-NLS-1$

	private static final String VERSION_OPEN_TAG = "<version>"; //$NON-NLS-1$
	private static final String VERSION_CLOSE_TAG = "</version>"; //$NON-NLS-1$

	private static final String REP_PLATFORM_OPEN_TAG = "<rep_platform>"; //$NON-NLS-1$
	private static final String REP_PLATFORM_CLOSE_TAG = "</rep_platform>"; //$NON-NLS-1$

	private static final String OP_SYS_OPEN_TAG = "<op_sys>"; //$NON-NLS-1$
	private static final String OP_SYS_CLOSE_TAG = "</op_sys>"; //$NON-NLS-1$

	private static final String BUG_STATUS_OPEN_TAG = "<bug_status>"; //$NON-NLS-1$
	private static final String BUG_STATUS_CLOSE_TAG = "</bug_status>"; //$NON-NLS-1$

	private static final String RESOLUTION_OPEN_TAG = "<resolution>"; //$NON-NLS-1$
	private static final String RESOLUTION_CLOSE_TAG = "</resolution>"; //$NON-NLS-1$

	private static final String BUG_SEVERITY_OPEN_TAG = "<bug_severity>"; //$NON-NLS-1$
	private static final String BUG_SEVERITY_CLOSE_TAG = "</bug_severity>"; //$NON-NLS-1$

	private static final String ASSIGNED_TO_CLOSE_TAG = "</assigned_to>"; //$NON-NLS-1$

	private static final String BUG_NOT_FOUND_TAG = "<bug error=\"NotFound\">"; //$NON-NLS-1$

	private static final File HTML_FILE_MESSAGES = new File(
			System.getProperty("user.home") + File.separator + "public_html" + File.separator + "messages.html"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	private static final File HTML_FILE_COMMANDS = new File(
			System.getProperty("user.home") + File.separator + "public_html" + File.separator + "commands.html"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

	private static final String URL_REGEX = "(http://.+|https://.+|ftp://.+)"; //$NON-NLS-1$
	private static final String CMD_REGEX = "(~.+)"; //$NON-NLS-1$
	private static final String BINDING_REGEX = "(\\{[0-9]+\\})"; //$NON-NLS-1$

	private static final Pattern URL_PATTERN = Pattern.compile(URL_REGEX);
	private static final Pattern CMD_PATTERN = Pattern.compile(CMD_REGEX);
	private static final Pattern BINDING_PATTERN = Pattern
			.compile(BINDING_REGEX);

	private Map messageSenders;
	private Map newsgroups;
	private Set operators;
	private Properties messages;
	private Properties commands;
	private JavadocAnalyzer analyzer;

	private IContainer container;

	private IChatMessageSender chatMessageSender;
	
	/**
	 * The name of this bot. May be <code>null</code> if the name could not be retrieved from the container.
	 */
	private String botName;

	private String password;

	private static final String xmlDecode(String string) {
		if (string == null || string.equals("")) { //$NON-NLS-1$
			return ""; //$NON-NLS-1$
		}

		int index = string.indexOf("&amp;"); //$NON-NLS-1$
		while (index != -1) {
			string = string.substring(0, index) + '&'
					+ string.substring(index + 5);
			index = string.indexOf("&amp;", index + 1); //$NON-NLS-1$
		}

		index = string.indexOf("&quot;"); //$NON-NLS-1$
		while (index != -1) {
			string = string.substring(0, index) + '"'
					+ string.substring(index + 6);
			index = string.indexOf("&quot;", index + 1); //$NON-NLS-1$
		}

		index = string.indexOf("&apos;"); //$NON-NLS-1$
		while (index != -1) {
			string = string.substring(0, index) + '\''
					+ string.substring(index + 6);
			index = string.indexOf("&apos;", index + 1); //$NON-NLS-1$
		}

		index = string.indexOf("&lt;"); //$NON-NLS-1$
		while (index != -1) {
			string = string.substring(0, index) + '<'
					+ string.substring(index + 4);
			index = string.indexOf("&lt;", index + 1); //$NON-NLS-1$
		}

		index = string.indexOf("&gt;"); //$NON-NLS-1$
		while (index != -1) {
			string = string.substring(0, index) + '>'
					+ string.substring(index + 4);
			index = string.indexOf("&gt;", index + 1); //$NON-NLS-1$
		}
		return string;
	}

	public ChatRoomMessageHandler() {
		messageSenders = new HashMap();
		analyzer = new JavadocAnalyzer();

		try {
			parseOperators();
		} catch (Exception e) {
			operators = Collections.EMPTY_SET;
		}

		try {
			parseMessages();
		} catch (Exception e) {
			messages = new Properties();
		}

		try {
			parseCommands();
		} catch (Exception e) {
			commands = new Properties();
		}

		try {
			writeCommandsToHTML();
		} catch (Exception e) {
			e.printStackTrace();
		}			 

		try {
			parseNewsgroup();
		} catch (Exception e) {
			newsgroups = Collections.EMPTY_MAP;
		}
	}

	private void parseOperators() throws IOException {
		Properties properties = new Properties();
		InputStream stream = FileLocator.openStream(Activator.getBundle(),
				new Path("operators.properties"), false);
		properties.load(stream);
		stream.close();
		String operatorString = properties.getProperty("operators");
		String[] operators = operatorString.split(",");
		this.operators = new HashSet(operators.length);
		for (int i = 0; i < operators.length; i++) {
			this.operators.add(operators[i].trim());
		}
	}

	private void parseMessages() throws IOException {
		messages = new Properties();
		InputStream stream = FileLocator.openStream(Activator.getBundle(),
				new Path("messages.properties"), false);
		messages.load(stream);
		stream.close();
	}

	/*
	 * collect commands from custom.properties -- only want those for which
	 * there's a matching *_Regex key/value pair, eg., EclipseHelp +
	 * EclipseHelp_Regex
	 */
	private void parseCommands() throws IOException {
		commands = new Properties();
		Properties commandsAll = new Properties();
		commandsAll.load(ChatRoomMessageHandler.class
				.getResourceAsStream("custom.properties")); //$NON-NLS-1$
		Enumeration keys = commandsAll.keys();
		while (keys.hasMoreElements()) {
			String key = (String) keys.nextElement();
			String keyRegex = key + "_Regex"; //$NON-NLS-1$
			if (commandsAll.keySet().contains(keyRegex)) {
				commands.setProperty(commandsAll.get(keyRegex).toString(),
						commandsAll.get(key).toString());
			}
		}
	}

	private void parseNewsgroup() throws IOException {
		Properties properties = new Properties();
		properties.load(JavadocAnalyzer.class
				.getResourceAsStream("newsgroup.txt"));
		newsgroups = new HashMap();
		for (Iterator it = properties.keySet().iterator(); it.hasNext();) {
			Object key = it.next();
			Object value = properties.get(key);
			newsgroups.put(key, value);
			newsgroups.put(value, value);
		}
	}

	private void sendMessage(ID id, String message) {
		try {
			if (container != null) {
				IChatRoomMessageSender sender = (IChatRoomMessageSender) messageSenders
						.get(id);
				if (sender == null) {
					chatMessageSender.sendChatMessage(id, message);
				} else {
					sender.sendMessage(message);
				}
			}
		} catch (ECFException e) {
			e.printStackTrace();
			container.disconnect();
			container = null;
		}
	}

	private void sendBug(ID roomID, String target, String number, String comment) {
		String urlString = BUG_DATABASE_PREFIX + number;
		if (comment != null) {
			urlString = urlString + "#c" + comment; //$NON-NLS-1$
		}
		try {
			HttpURLConnection hURL = (HttpURLConnection) new URL(
					BUG_DATABASE_PREFIX + number + BUG_DATABASE_POSTFIX)
					.openConnection();
			hURL.setAllowUserInteraction(true);
			hURL.connect();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					hURL.getInputStream()));
			StringBuffer buffer = new StringBuffer();
			try {
				if (hURL.getResponseCode() != HttpURLConnection.HTTP_OK) {
					sendMessage(roomID, (target != null ? target + ": " : "")
							+ NLS.bind(CustomMessages.Bug, number, urlString));
					return;
				}

				String input = reader.readLine();
				synchronized (buffer) {
					buffer.append(input);
					while (input != null
							&& input.indexOf(ASSIGNED_TO_CLOSE_TAG) == -1) {
						if (input.indexOf(BUG_NOT_FOUND_TAG) != -1) { /*
																		 * handle
																		 * case
																		 * where
																		 * bug
																		 * does
																		 * not
																		 * exist,
																		 * eg.
																		 * ~bug1234
																		 */
							sendMessage(
									roomID,
									(target != null ? target + ": " : "")
											+ NLS
													.bind(
															CustomMessages
																	.getString(CustomMessages.Bug_Not_Found),
															number));
							return;
						}
						input = reader.readLine();
						buffer.append(input);
					}
				}
				hURL.disconnect();
			} catch (EOFException e) {
				hURL.disconnect();
				sendMessage(roomID, (target != null ? target + ": " : "")
						+ NLS.bind(CustomMessages.Bug, number, urlString));
				e.printStackTrace();
				return;
			}
			String webPage = buffer.toString();
			int summaryStartIndex = webPage.indexOf(SHORT_DESC_OPEN_TAG);
			int summaryEndIndex = webPage.indexOf(SHORT_DESC_CLOSE_TAG,
					summaryStartIndex);
			if (summaryStartIndex != -1 & summaryEndIndex != -1) {
				try {
					String summary = webPage.substring(summaryStartIndex
							+ SHORT_DESC_OPEN_TAG.length(), summaryEndIndex);
					String product = webPage.substring(webPage
							.indexOf(PRODUCT_OPEN_TAG)
							+ PRODUCT_OPEN_TAG.length(), webPage
							.indexOf(PRODUCT_CLOSE_TAG));
					String component = webPage.substring(webPage
							.indexOf(COMPONENT_OPEN_TAG)
							+ COMPONENT_OPEN_TAG.length(), webPage
							.indexOf(COMPONENT_CLOSE_TAG));
					String version = webPage.substring(webPage
							.indexOf(VERSION_OPEN_TAG)
							+ VERSION_OPEN_TAG.length(), webPage
							.indexOf(VERSION_CLOSE_TAG));
					String platform = webPage.substring(webPage
							.indexOf(REP_PLATFORM_OPEN_TAG)
							+ REP_PLATFORM_OPEN_TAG.length(), webPage
							.indexOf(REP_PLATFORM_CLOSE_TAG));
					String os = webPage.substring(webPage
							.indexOf(OP_SYS_OPEN_TAG)
							+ OP_SYS_OPEN_TAG.length(), webPage
							.indexOf(OP_SYS_CLOSE_TAG));
					String status = webPage.substring(webPage
							.indexOf(BUG_STATUS_OPEN_TAG)
							+ BUG_STATUS_OPEN_TAG.length(), webPage
							.indexOf(BUG_STATUS_CLOSE_TAG));
					String severity = webPage.substring(webPage
							.indexOf(BUG_SEVERITY_OPEN_TAG)
							+ BUG_SEVERITY_OPEN_TAG.length(), webPage
							.indexOf(BUG_SEVERITY_CLOSE_TAG));
					String assignee = webPage.substring(webPage.substring(0,
							webPage.indexOf(ASSIGNED_TO_CLOSE_TAG))
							.lastIndexOf('>') + 1, webPage
							.indexOf(ASSIGNED_TO_CLOSE_TAG));

					int resolutionStartIndex = webPage
							.indexOf(RESOLUTION_OPEN_TAG);
					if (resolutionStartIndex != -1) {
						String resolution = webPage.substring(
								resolutionStartIndex
										+ RESOLUTION_OPEN_TAG.length(), webPage
										.indexOf(RESOLUTION_CLOSE_TAG));
						sendMessage(roomID, (target != null ? target + ": "
								: "")
								+ NLS.bind(CustomMessages
										.getString(CustomMessages.BugContent),
										new Object[] { number, urlString,
												product, component, version,
												platform, os, status,
												resolution, severity, assignee,
												xmlDecode(summary) }));
					} else {
						sendMessage(roomID, (target != null ? target + ": "
								: "")
								+ NLS.bind(CustomMessages
										.getString(CustomMessages.BugContent2),
										new Object[] { number, urlString,
												product, component, version,
												platform, os, status, severity,
												assignee, xmlDecode(summary) }));
					}
				} catch (RuntimeException e) {
					sendMessage(roomID, (target != null ? target + ": " : "")
							+ NLS.bind(CustomMessages
									.getString(CustomMessages.Bug),
									new Object[] { number, urlString }));
				}
			} else {
				sendMessage(roomID, (target != null ? target + ": " : "")
						+ NLS.bind(
								CustomMessages.getString(CustomMessages.Bug),
								new Object[] { number, urlString }));
			}
		} catch (IOException e) {
			sendMessage(roomID, (target != null ? target + ": " : "")
					+ NLS.bind(CustomMessages.getString(CustomMessages.Bug),
							new Object[] { number, urlString }));
			e.printStackTrace();
		}
	}

	private void sendNewsgroupSearch(ID roomID, String target, String query) {
		String[] strings = query.split(" "); //$NON-NLS-1$
		if (strings.length == 1) {
			sendMessage(roomID, (target != null ? target + ": " : "")
					+ CustomMessages
							.getString(CustomMessages.NewsgroupSearch_Invalid));
			return;
		}
		for (int i = 0; i < strings.length; i++) {
			try {
				strings[i] = URLEncoder.encode(strings[i].trim(), "UTF-8"); //$NON-NLS-1$
			} catch (UnsupportedEncodingException e) {
				// technically this should never happen, but better safe than
				// sorry
				strings[i] = URLEncoder.encode(strings[i].trim());
			}
		}

		/*
		 * support either a lookup in the newsgroups static list, or input of
		 * eclipse.foo.bar as a presumed valid group
		 */
		String newsgroup = strings[0].startsWith("eclipse.") ? "news."
				+ strings[0] : (String) newsgroups.get(strings[0]);

		/*
		 * if newsgroup doesn't start with "eclipse." and lookup fails, we get
		 * back null; help the user when this happens
		 */
		if (newsgroup == null) {
			sendMessage(
					roomID,
					(target != null ? target + ": " : "")
							+ CustomMessages
									.getString(CustomMessages.NewsgroupSearch_InvalidGroup));
			return;
		}
		StringBuffer buffer = new StringBuffer();
		synchronized (buffer) {
			for (int i = 1; i < strings.length; i++) {
				buffer.append(strings[i] + '+');
			}
			buffer.deleteCharAt(buffer.length() - 1);
		}
		sendMessage(roomID, (target != null ? target + ": " : "")
				+ NLS.bind(CustomMessages
						.getString(CustomMessages.NewsgroupSearch), newsgroup,
						buffer.toString()));
	}

	private void sendGoogle(ID roomID, String target, String searchString) {
		searchString = searchString.replace(' ', '+');
		sendMessage(roomID, (target != null ? target + ": " : "")
				+ NLS.bind(CustomMessages.getString(CustomMessages.Google),
						searchString));
	}

	private void sendWiki(ID roomID, String target, String articleName) {
		articleName = articleName.replace(' ', '_');
		sendMessage(roomID, (target != null ? target + ": " : "")
				+ NLS.bind(CustomMessages.getString(CustomMessages.Wiki),
						articleName));
	}

	private void sendEclipseHelp(ID roomID, String target, String searchString) {
		searchString = searchString.replace(' ', '+');
		sendMessage(roomID, (target != null ? target + ": " : "")
				+ NLS.bind(
						CustomMessages.getString(CustomMessages.EclipseHelp),
						searchString));
	}

	private void sendJavaDoc(ID roomID, String target, String parameter) {
		String message = null;
		int index = parameter.indexOf('#');
		if (index == -1) {
			message = analyzer.getJavadocs(parameter);
		} else {
			String className = parameter.substring(0, index);
			parameter = parameter.substring(index + 1);
			index = parameter.indexOf('(');
			if (index == -1) {
				message = className + '#' + parameter + " - "
						+ analyzer.getJavadocs(className, parameter);
			} else {
				String method = parameter.substring(0, index);
				parameter = parameter.substring(index + 1);
				parameter = parameter.substring(0, parameter.indexOf(')'));
				String[] parameters = parameter.split(",");
				for (int i = 0; i < parameters.length; i++) {
					parameters[i] = parameters[i].trim();
				}
				message = className + '#' + method + " - "
						+ analyzer.getJavadocs(className, method, parameters);
			}
		}
		sendMessage(roomID, (target != null ? target + ": " : "") + message);
	}

	private void sendMessageList(ID roomID, String target) {
		sendMessage(roomID, (target != null ? target + ": " : "")
				+ CustomMessages.getString(CustomMessages.MessageList));
	}

	private void sendSearchPlugins(ID roomID, String target, String searchString) {
		searchString = searchString.replace(' ', '+');
		sendMessage(roomID, (target != null ? target + ": " : "")
				+ NLS.bind(CustomMessages
						.getString(CustomMessages.SearchPlugins), searchString));
	}

	private void sendCQ(ID roomID, String target, String id, String comment) {
		String suffix = id;
		if (comment != null) {
			suffix += "#c" + comment;
		}
		sendMessage(roomID, (target != null ? target + ": " : "")
				+ NLS.bind(CustomMessages.getString(CustomMessages.CQ), id,
						suffix));
	}

	private void writeToHTML(File file, String title, Properties properties)
			throws IOException {
		FileWriter out = new FileWriter(file);
		out
				.write("<html>\n<head><title>" + title + "</title></head>\n<body>\n<table cellspacing=\"2\" cellpadding=\"2\" border=\"0\">\n"); //$NON-NLS-1$
		Set set = properties.keySet();
		String[] propertiesSorted = (String[]) set.toArray(new String[set
				.size()]);
		Arrays.sort(propertiesSorted);

		for (int i = 0; i < propertiesSorted.length; i++) {
			String output = properties.getProperty(propertiesSorted[i]);
			out.write(formatTableRow(propertiesSorted[i], output));
		}

		out.write("</table>\n</body></html>\n"); //$NON-NLS-1$
		out.flush();

		try {
			out.close();
		} catch (IOException e) {
			// ignored
		}
	}

	private void writeMessagesToHTML() throws IOException {
		writeToHTML(HTML_FILE_MESSAGES, "KOS-MOS Messages", messages); //$NON-NLS-1$
	}

	private void writeCommandsToHTML() throws IOException {
		writeToHTML(HTML_FILE_COMMANDS, "KOS-MOS Commands", commands); //$NON-NLS-1$
	}

	private String formatTableRow(String key, String val) {
		return "<tr valign=\"top\"><td><b>" //$NON-NLS-1$
				+ key.replaceAll(" ", "&#160;") //$NON-NLS-1$ //$NON-NLS-2$ 
				+ "</b></td><td>" //$NON-NLS-1$
				+ text2html(val)
				+ "</td></tr>\n<tr><td colspan=\"2\"><hr noshade=\"noshade\" size=\"1\" width=\"100%\"/></td></tr>\n\n"; //$NON-NLS-1$
	}

	private String text2html(String val) {
		StringTokenizer st = new StringTokenizer(val, " )(\"", true); //$NON-NLS-1$
		StringBuffer sb = new StringBuffer();
		while (st.hasMoreTokens()) {
			String tok = st.nextToken();
			Matcher patternMatcher = URL_PATTERN.matcher(tok);
			if (patternMatcher.matches()) {
				sb.append("<a href=\""); //$NON-NLS-1$
				sb.append(patternMatcher.group(1));
				sb.append("\">"); //$NON-NLS-1$
				if (patternMatcher.group(1).length() >= 120) // break long
				// URLs
				{
					StringTokenizer st2 = new StringTokenizer(patternMatcher
							.group(1), " /&", true); //$NON-NLS-1$
					StringBuffer sb2 = new StringBuffer();
					while (st2.hasMoreTokens()) {
						sb2.append(st2.nextToken());
						if (sb2.length() >= 100) {
							sb2.append(" "); //$NON-NLS-1$ 
						}
					}
					sb.append(sb2.toString().replaceAll(BINDING_REGEX,
							"<b style=\"color:green\">$1</b>")); //$NON-NLS-1$ 
				} else {
					sb.append(patternMatcher.group(1).replaceAll(BINDING_REGEX,
							"<b style=\"color:green\">$1</b>")); //$NON-NLS-1$ 
				}
				sb.append("</a>"); //$NON-NLS-1$
			} else {
				Matcher cmdMatcher = CMD_PATTERN.matcher(tok);
				if (cmdMatcher.matches()) {
					sb.append("<b style=\"color:red\">"); //$NON-NLS-1$
					sb.append(cmdMatcher.group(1));
					sb.append("</b>"); //$NON-NLS-1$
				} else {
					Matcher bindingMatcher = BINDING_PATTERN.matcher(tok);
					if (bindingMatcher.matches()) {
						sb.append("<b style=\"color:green\">"); //$NON-NLS-1$
						sb.append(bindingMatcher.group(1));
						sb.append("</b>"); //$NON-NLS-1$
					} else {
						sb.append(tok);
					}
				}
			}
		}
		return sb.toString();
	}

	private boolean isProcessed(ID roomID, String target, String msg) {
		String reply = (String) messages.get(msg);
		if (reply == null) {
			return false;
		}
		sendMessage(roomID, (target != null ? target + ": " : "") + reply); //$NON-NLS-1$
		return true;
	}

	private void learn(ID roomID, String contents) {
		String key = contents.split(" ")[0].toLowerCase();
		try {
			URL url = FileLocator.find(Activator.getBundle(), new Path(
					"messages.properties"), null);
			url = FileLocator.resolve(url);

			String property = messages.getProperty(key);
			if (property == null) {
				OutputStream stream = new FileOutputStream(url.getPath());
				messages.setProperty(key, contents.substring(key.length())
						.trim());
				messages.store(stream, LICENSE);
				writeMessagesToHTML();
				sendMessage(roomID, NLS.bind(CustomMessages
						.getString(CustomMessages.Learn_Reply), key));
			} else {
				sendMessage(roomID, NLS.bind(CustomMessages
						.getString(CustomMessages.Learn_Conflict), key,
						property));
			}
		} catch (Exception e) {
			sendMessage(roomID, NLS.bind(CustomMessages
					.getString(CustomMessages.Learn_Failure), key));
		}
	}

	private void update(ID roomID, String contents) {
		String key = contents.split(" ")[0].toLowerCase();
		try {
			URL url = FileLocator.find(Activator.getBundle(), new Path(
					"messages.properties"), null);
			url = FileLocator.resolve(url);

			OutputStream stream = new FileOutputStream(url.getPath());
			messages.setProperty(key, contents.substring(key.length()).trim());
			messages.store(stream, LICENSE);
			writeMessagesToHTML();
			sendMessage(roomID, NLS.bind(CustomMessages
					.getString(CustomMessages.Learn_Update), key));
		} catch (Exception e) {
			sendMessage(roomID, NLS.bind(CustomMessages
					.getString(CustomMessages.Learn_Failure), key));
		}
	}

	private void remove(ID roomID, String contents) {
		String key = contents.split(" ")[0].toLowerCase();
		try {
			URL url = FileLocator.find(Activator.getBundle(), new Path(
					"messages.properties"), null);
			url = FileLocator.resolve(url);

			OutputStream stream = new FileOutputStream(url.getPath());
			messages.remove(key);
			messages.store(stream, LICENSE);
			writeMessagesToHTML();
			sendMessage(roomID, NLS.bind(CustomMessages
					.getString(CustomMessages.Learn_Remove), key));
		} catch (Exception e) {
			sendMessage(roomID, NLS.bind(CustomMessages
					.getString(CustomMessages.Learn_Failure), key));
		}
	}

	private void send(ID fromID, ID roomID, String target, String msg) {
		/* handle operator-added messages - see messages.properties */
		if (isProcessed(roomID, target, msg)) {
			return;
		}

		/* handle custom commands - see custom.properties */
		Matcher cmdMatcher = null;
		Enumeration keys = commands.keys();
		while (keys.hasMoreElements()) {
			String key = (String) keys.nextElement();
			Pattern pattern = Pattern.compile(key);
			cmdMatcher = pattern.matcher(msg);
			if (cmdMatcher.matches()) {
				break;
			}
		}

		if (cmdMatcher != null && cmdMatcher.matches()) {
			if (cmdMatcher.group(1).equals("add ")) { //$NON-NLS-1$
				if (operators.contains(fromID.getName())) {
					learn(roomID, cmdMatcher.group(2));
				} else {
					sendMessage(roomID, NLS.bind(CustomMessages
							.getString(CustomMessages.No_Operation_Privileges),
							fromID.getName()));
				}
			} else if (cmdMatcher.group(1).equals("set ") || cmdMatcher.group(1).equals("update ")) { //$NON-NLS-1$ //$NON-NLS-2$
				if (operators.contains(fromID.getName())) {
					update(roomID, cmdMatcher.group(2));
				} else {
					sendMessage(roomID, NLS.bind(CustomMessages
							.getString(CustomMessages.No_Operation_Privileges),
							fromID.getName()));
				}
			} else if (cmdMatcher.group(1).equals("remove ")) { //$NON-NLS-1$
				if (operators.contains(fromID.getName())) {
					remove(roomID, cmdMatcher.group(2));
				} else {
					sendMessage(roomID, NLS.bind(CustomMessages
							.getString(CustomMessages.No_Operation_Privileges),
							fromID.getName()));
				}
			} else if (cmdMatcher.group(1).equals("") || cmdMatcher.group(1).equals("bug") || cmdMatcher.group(1).equals("bug ")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				msg = cmdMatcher.group(2);
				int index = msg.indexOf('c');
				if (index == -1) {
					try {
						// try to parse the string to see that we have a valid
						// number
						Integer.parseInt(msg);
						sendBug(roomID, target, msg, null);
					} catch (NumberFormatException e) {
						// ignored
					}
				} else {
					try {
						// try to parse the string to see that we have a valid
						// number
						Integer.parseInt(msg.substring(0, index));
						sendBug(roomID, target, msg.substring(0, index), msg
								.substring(index + 1));
					} catch (NumberFormatException e) {
						// ignored
					}
				}
			} else if (cmdMatcher.group(1).equals("cq") || cmdMatcher.group(1).equals("cq ")) { //$NON-NLS-1$ //$NON-NLS-2$
				msg = cmdMatcher.group(2);
				int index = msg.indexOf('c');
				if (index == -1) {
					try {
						// try to parse the string to see that we have a valid
						// number
						Integer.parseInt(msg);
						sendCQ(roomID, target, msg, null);
					} catch (NumberFormatException e) {
						// ignored
					}
				} else {
					try {
						// try to parse the string to see that we have a valid
						// number
						Integer.parseInt(msg.substring(0, index));
						sendCQ(roomID, target, msg.substring(0, index), msg
								.substring(index + 1));
					} catch (NumberFormatException e) {
						// ignored
					}
				}
			} else if (cmdMatcher.group(1).equals("javadoc ") || cmdMatcher.group(1).equals("api ")) { //$NON-NLS-1$ //$NON-NLS-2$
				sendJavaDoc(roomID, target, cmdMatcher.group(2));
			} else if (cmdMatcher.group(1).equals("news ") || cmdMatcher.group(1).equals("newsgroup ")) { //$NON-NLS-1$ //$NON-NLS-2$
				sendNewsgroupSearch(roomID, target, cmdMatcher.group(2));
			} else if (cmdMatcher.group(1).equals("g ")) { //$NON-NLS-1$
				sendGoogle(roomID, target, cmdMatcher.group(2));
			} else if (cmdMatcher.group(1).equals("wiki ")) { //$NON-NLS-1$
				sendWiki(roomID, target, cmdMatcher.group(2));
			} else if (cmdMatcher.group(1).equals("eh ")) { //$NON-NLS-1$
				sendEclipseHelp(roomID, target, cmdMatcher.group(2));
			} else if (cmdMatcher.group(1).equals("list")) { //$NON-NLS-1$
				sendMessageList(roomID, target);
			} else if (cmdMatcher.group(1).equals("searchplugins ")) { //$NON-NLS-1$
				sendSearchPlugins(roomID, target, cmdMatcher.group(2));
			}
		}
	}

	private String[] parseInput(String msg) {
		if (msg.startsWith("tell")) { //$NON-NLS-1$
			msg = msg.substring(5);
			int index = msg.indexOf(' ');
			if (index == -1) {
				return null;
			}
			String user = msg.substring(0, index);
			msg = msg.substring(index + 1);
			index = msg.indexOf(' ');
			if (index == -1) {
				return null;
			}
			String tmp = msg.substring(0, index);
			if (tmp.equals("about")) { //$NON-NLS-1$
				msg = msg.substring(index + 1);
			}
			return new String[] { user, msg };
		} else {
			return new String[] { null, msg };
		}
	}

	private void handleMessage(ID fromID, ID roomID, String message) {
		try {
			String[] info = parseInput(message);
			if (info != null) {
				send(fromID, roomID, info[0], info[1]);
			}
		} catch (RuntimeException e) {
			e.printStackTrace();
		}
	}

	public void handleRoomMessage(IChatRoomMessage message) {
		ID fromID = message.getFromID();
		String name = fromID.getName();
		if (name.charAt(0) == '#' || name.equals(botName)) { // skip messages
			// from the
			// channel or
			// self
			return;
		}

		String msg = message.getMessage();
		switch (msg.charAt(0)) {
		case '~':
		case '!':
			msg = msg.substring(1).trim();
			int index = msg.indexOf(' ');
			if (index == -1) {
				handleMessage(fromID, message.getChatRoomID(), msg
						.toLowerCase());
			} else {
				handleMessage(fromID, message.getChatRoomID(), msg.substring(0,
						index).toLowerCase()
						+ msg.substring(index));
			}
			break;
		default:
			String upperCase = msg.toUpperCase();
			if (upperCase.startsWith("KOS-MOS:")
					|| upperCase.startsWith("KOS-MOS,")) {
				msg = upperCase.substring(8).trim();
				switch (msg.charAt(0)) {
				case '~':
				case '!':
					msg = msg.substring(1).trim();
					index = msg.indexOf(' ');
					if (index == -1) {
						handleMessage(fromID, message.getChatRoomID(), msg
								.toLowerCase());
					} else {
						handleMessage(fromID, message.getChatRoomID(), msg
								.substring(0, index).toLowerCase()
								+ msg.substring(index));
					}
					break;
				}
			} else {
				String[] split = msg.split("\\s"); //$NON-NLS-1$
				for (int i = 0; i < split.length; i++) {
					if (split[i].length() > 0) {
						switch (split[i].charAt(0)) {
						case '~':
						case '!':
							handleMessage(fromID, message.getChatRoomID(),
									split[i].substring(1).trim().toLowerCase());
							break;
						}
					}
				}
			}
		}
	}

	public void init(IChatRoomBotEntry robot) {
		// nothing to do
	}

	public void preChatRoomConnect(IChatRoomContainer roomContainer, ID roomID) {
		// retrieve our name
		ID connectedID = container.getConnectedID();
		botName = connectedID.getName();
		IChatID chatID = (IChatID) connectedID.getAdapter(IChatID.class);
		if (chatID != null) {
			botName = chatID.getUsername();
		}
		
		messageSenders.put(roomID, roomContainer.getChatRoomMessageSender());
		if (password != null) {
			try {
				sendMessage(IDFactory.getDefault().createStringID("nickserv"),
						"identify " + password);
			} catch (IDCreateException e) {
			}
		}
	}

	public void preContainerConnect(IContainer container, ID targetID) {
		File file = new File(Platform.getInstanceLocation().getURL().getPath(),
				"password.properties");
		if (file.exists()) {
			Properties properties = new Properties();
			try {
				properties.load(new FileInputStream(file));
				password = properties.getProperty("password");
			} catch (FileNotFoundException e) {
			} catch (IOException e) {
			}
		}
		this.container = container;
		IChatRoomContainer chatRoomContainer = (IChatRoomContainer) container
				.getAdapter(IChatRoomContainer.class);
		chatMessageSender = chatRoomContainer.getPrivateMessageSender();
		chatRoomContainer.addMessageListener(new IIMMessageListener() {
			public void handleMessageEvent(IIMMessageEvent e) {
				if (e instanceof IChatMessageEvent) {
					IChatMessageEvent event = (IChatMessageEvent) e;
					String msg = event.getChatMessage().getBody();
					switch (msg.charAt(0)) {
					case '~':
					case '!':
						handleMessage(event.getFromID(), event.getFromID(), msg
								.substring(1).trim());
						break;
					default:
						handleMessage(event.getFromID(), event.getFromID(), msg
								.trim());
						break;
					}
				}
			}
		});
	}

}
