/*******************************************************************************
 * Copyright (c) 2009 Nokia 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:
 * Nokia - Initial API and implementation
 *******************************************************************************/

package org.eclipse.cdt.debug.edc.ui.console;

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

import org.eclipse.cdt.debug.edc.internal.EDCDebugger;
import org.eclipse.cdt.debug.edc.internal.ui.IconAndMessageAndDetailsDialog;
import org.eclipse.cdt.debug.edc.tcf.extension.services.ILogging;
import org.eclipse.cdt.debug.edc.tcf.extension.services.ILogging.DoneAddListener;
import org.eclipse.cdt.debug.edc.tcf.extension.services.ILogging.DoneRemoveListener;
import org.eclipse.cdt.debug.edc.tcf.extension.services.ILogging.LogListener;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.tm.tcf.core.AbstractChannel;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.IChannel.IChannelListener;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.util.TCFTask;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleListener;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;

/**
 * A class that manages connecting an ILogging with an IConsole
 */
public class ConsoleLogManager implements LogListener {

	/**
	 * List of created managers
	 */
	private static List<ConsoleLogManager> managers;

	/**
	 * The IChannel
	 */
	private IChannel channel;

	/**
	 * The managed consoles
	 */
	private Map<MessageConsole, MessageConsoleStream> consoleStreamMappings;

	/**
	 * The identifier of the log
	 */
	private final String logId;

	/**
	 * The type id of the managed consoles
	 */
	private final String consoleType;

	private IChannelListener channelOpenListener;

	/**
	 * Create a new manager to manager a console type with a specific ILogging
	 * service log id and channel
	 * 
	 * @param consoleType
	 *            String
	 * @param logId
	 *            String
	 * @param channel
	 *            IChannel
	 */
	public static ConsoleLogManager create(String consoleType, String logId, IChannel channel) {
		if (managers == null)
			managers = new ArrayList<ConsoleLogManager>();

		ConsoleLogManager consoleStreamManager = new ConsoleLogManager(consoleType, logId, channel);
		managers.add(consoleStreamManager);
		return consoleStreamManager;
	}

	public static ConsoleLogManager findExisting(String consoleType, String logId, IChannel channel) {
		if (managers != null) {
			for (ConsoleLogManager consoleLogManager : managers) {
				if (consoleLogManager.consoleType.equals(consoleType) && consoleLogManager.logId.equals(logId)
						&& consoleLogManager.channel.equals(channel))
					return consoleLogManager;
			}
		}
		return null;
	}

	private ConsoleLogManager(final String consoleType, String logId, IChannel channel) {
		this.consoleType = consoleType;
		this.logId = logId;
		this.channel = channel;
		hookChannel(channel);

		consoleStreamMappings = new HashMap<MessageConsole, MessageConsoleStream>();

		ConsolePlugin.getDefault().getConsoleManager().addConsoleListener(new IConsoleListener() {
			public void consolesRemoved(IConsole[] consoles) {
				for (IConsole console : consoles) {
					if (console instanceof MessageConsole) {
						removeConsole((MessageConsole) console);
					}
				}
			}

			public void consolesAdded(IConsole[] consoles) {
				for (IConsole console : consoles) {
					String type = console.getType();
					if (type != null && type.equals(consoleType) && console instanceof MessageConsole) {
						addConsole((MessageConsole) console);
					}
				}
			}
		});
	}

	
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((consoleType == null) ? 0 : consoleType.hashCode());
		result = prime * result + ((logId == null) ? 0 : logId.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ConsoleLogManager other = (ConsoleLogManager) obj;
		if (consoleType == null) {
			if (other.consoleType != null)
				return false;
		} else if (!consoleType.equals(other.consoleType))
			return false;
		if (logId == null) {
			if (other.logId != null)
				return false;
		} else if (!logId.equals(other.logId))
			return false;
		return true;
	}

	private void hookChannel(final IChannel channel) {
		Protocol.invokeAndWait(new Runnable() {
			public void run() {
				channel.addChannelListener(new IChannelListener() {

					public void onChannelOpened() {
					}

					public void onChannelClosed(Throwable error) {
						managers.remove(ConsoleLogManager.this);
					}

					public void congestionLevel(int level) {
					}
				});
			}
		});
	}

	public void removeConsole(MessageConsole console) {
		if (consoleStreamMappings.remove(console) != null && consoleStreamMappings.isEmpty()) {
			if (isChannelOpen()) {
				Job job = new Job("Disabling console logging") { //$NON-NLS-1$
					@Override
					protected IStatus run(IProgressMonitor monitor) {

						TCFTask<Object> task = new TCFTask<Object>() {
							public void run() {
								ILogging logging = ConsoleLogManager.this.channel.getRemoteService(ILogging.class);
								assert logging != null;
								logging.removeListener(logId, ConsoleLogManager.this, new DoneRemoveListener() {
									public void doneRemoveListener(IToken token, Exception error) {
										if (error == null)
											done(this);
										else
											error(error);
									}
								});
							}
						};
						// wait a fixed time since the target may be disconnected
						try {
							task.get(15, TimeUnit.SECONDS);
						} catch (InterruptedException e) {
						} catch (Exception e) {
							EDCDebugger.getMessageLogger().logError(null, e);
						}

						return Status.OK_STATUS;
					}
				};
				job.setSystem(true);
				job.schedule();
			}
		}
	}

	public void addConsole(MessageConsole console) {
		if (consoleStreamMappings.isEmpty()) {
			if (isChannelOpen()) {
				addLoggingListener();
			} else {
				channelOpenListener = new IChannelListener() {
					
					public void onChannelOpened() {
						addLoggingListener();
						channel.removeChannelListener(channelOpenListener);
					}
					
					public void onChannelClosed(Throwable error) {
					}
					
					public void congestionLevel(int level) {
					}
				};
				Protocol.invokeAndWait(new Runnable() {
					public void run() {
						channel.addChannelListener(channelOpenListener);
					}
				});
			}
		}
		consoleStreamMappings.put(console, console.newMessageStream());
	}

	/**
	 * 
	 */
	private void addLoggingListener() {
		Protocol.invokeAndWait(new Runnable() {
			public void run() {
				ILogging logging = ConsoleLogManager.this.channel.getRemoteService(ILogging.class);
				assert logging != null;
				if (logging != null)
					logging.addListener(logId, ConsoleLogManager.this, new DoneAddListener() {
						public void doneAddListener(IToken token, Exception error) {
							if (error != null)
								EDCDebugger.getMessageLogger().logError("Failed to add logging listener", error);
						}
					});
			}
		});
	}

	private boolean isChannelOpen() {
		int state = ((AbstractChannel) channel).getState();
		return state == IChannel.STATE_OPEN || state == IChannel.STATE_OPENING;
	}

	public void appendText(final MessageConsole console, final String text, boolean eol) {
		MessageConsoleStream stream = consoleStreamMappings.get(console);
		if (stream.isClosed()) {
			stream = console.newMessageStream();
			consoleStreamMappings.put(console, stream);
		}
		if (eol)
			stream.println(text);
		else
			stream.print(text);
	}

	public void write(String msg) {
		for (MessageConsole console : consoleStreamMappings.keySet()) {
			appendText(console, msg, false);
		}
	}

	public void writeln(String msg) {
		for (MessageConsole console : consoleStreamMappings.keySet()) {
			appendText(console, msg, true);
		}
	}


	private static String severityString(final int severity) {
		String result;
		switch (severity) {
			case IStatus.INFO:		result = "INFO";	break;
			case IStatus.WARNING:	result = "WARNING";	break;
			case IStatus.ERROR:
			default:	// shouldn't be receiving anything but what's above
				result = "ERROR";
		}
		return result;
	}

	/** @since 2.0 */
	public void dialog(final int severity, final String summary, final String details) {
		String edcId = EDCDebugger.getUniqueIdentifier();
		EDCDebugger.getMessageLogger().log(new Status(severity, edcId, "EDC debugger: " + summary));

		CDebugUIPlugin.getStandardDisplay().asyncExec(new Runnable() {
			public void run() {
				(new IconAndMessageAndDetailsDialog(severity, summary, 
													"EDC debugger reports "
													+ severityString(severity)
													+ ":\n\n" + details))
				.open();
			}
		});
	}

	static void removeManagersForChannel(IChannel channel) {
		if (managers != null) {
			for (ConsoleLogManager consoleLogManager : managers.toArray(new ConsoleLogManager[managers.size()])) {
				if (consoleLogManager.channel.equals(channel))
					managers.remove(consoleLogManager);
			}
		}
	}
}
