/*******************************************************************************
 * Copyright (c) 2010 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.internal.ui;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.cdt.debug.edc.internal.EDCDebugger;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.tm.tcf.core.AbstractChannel;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.IPeer;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

public class TraceView extends ViewPart implements Protocol.ChannelOpenListener {

	private static final String FILTER_HEARTBEATS = "filter_heartbeats"; //$NON-NLS-1$
	private static final String REUSE_TABS = "reuse_tabs"; //$NON-NLS-1$

	private Composite parent;
	private TabFolder tabs;
	private Label no_data;
	private final Map<TabItem, Page> tab2page = new HashMap<TabItem, Page>();
	private Action clearTabAction;
	private Action closeTabAction;
	private Action exportAction;
	private Action filterAction;
	private Action reuseAction;
	private IMemento memento;

	private class Page implements AbstractChannel.TraceListener {

		final AbstractChannel channel;

		private TabItem tab;
		private Text text;

		private final StringBuffer bf = new StringBuffer();
		private int bf_line_cnt = 0;
		private boolean closed;

		private final Thread update_thread = new Thread() {
			@Override
			public void run() {
				synchronized (Page.this) {
					while (!closed) {
						if (bf_line_cnt > 0) {
							Runnable r = new Runnable() {
								public void run() {
									String str = null;
									int cnt = 0;
									synchronized (Page.this) {
										str = bf.toString();
										cnt = bf_line_cnt;
										bf.setLength(0);
										bf_line_cnt = 0;
									}
									if (text == null)
										return;
									if (text.getLineCount() > 1000 - cnt) {
										String s = text.getText();
										int n = 0;
										int i = -1;
										while (n < cnt) {
											int j = s.indexOf('\n', i + 1);
											if (j < 0)
												break;
											i = j;
											n++;
										}
										if (i >= 0) {
											text.setText(s.substring(i + 1));
										}
									}
									text.append(str);
								}
							};
							getSite().getShell().getDisplay().asyncExec(r);
						}
						try {
							Page.this.wait(1000);
						} catch (InterruptedException e) {
							break;
						}
					}
				}
			}
		};

		Page(AbstractChannel channel) {
			this.channel = channel;
			update_thread.start();
		}

		public void dispose() {
			synchronized (this) {
				closed = true;
				update_thread.interrupt();
			}
			try {
				update_thread.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			tab2page.remove(tab);
			tab.dispose();
			tab = null;
			text = null;
			if (tab2page.isEmpty())
				hideTabs();
		}

		public synchronized void onChannelClosed(Throwable error) {
			String msg = "";
			
			if (error == null) {
				msg = "Channel closed";
			} else {
				msg = "Channel terminated: " + error;
			}

			bf.append("\n<================= " + msg + " =================>\n");
			bf_line_cnt += 3;

			getSite().getShell().getDisplay().asyncExec(new Runnable() {
				public void run() {
					updateCloseAction();
				}
			});
		}

		public synchronized void onMessageReceived(char type, String token, String service, String name, byte[] data) {
			if (memento.getBoolean(FILTER_HEARTBEATS)) {
				if (name != null && name.contains("HeartBeat"))
					return;
			}

			try {
				bf.append("Time(ms): " + System.currentTimeMillis() + " Inp: " );
				bf.append(type);
				if (token != null) {
					bf.append(' ');
					bf.append(token);
				}
				if (service != null) {
					bf.append(' ');
					bf.append(service);
				}
				if (name != null) {
					bf.append(' ');
					bf.append(name);
				}
				if (data != null) {
					int i = 0;
					while (i < data.length) {
						int j = i;
						while (j < data.length && data[j] != 0)
							j++;
						bf.append(' ');
						bf.append(new String(data, i, j - i, "UTF8"));
						if (j < data.length && data[j] == 0)
							j++;
						i = j;
					}
				}
				bf.append('\n');
				bf_line_cnt++;
			} catch (UnsupportedEncodingException x) {
				x.printStackTrace();
			}
		}

		public synchronized void onMessageSent(char type, String token, String service, String name, byte[] data) {
			if (memento.getBoolean(FILTER_HEARTBEATS)) {
				if (name != null && name.contains("HeartBeat"))
					return;
			}

			try {
				bf.append("Time(ms): " + System.currentTimeMillis() + " Out: ");
				bf.append(type);
				if (token != null) {
					bf.append(' ');
					bf.append(token);
				}
				if (service != null) {
					bf.append(' ');
					bf.append(service);
				}
				if (name != null) {
					bf.append(' ');
					bf.append(name);
				}
				if (data != null) {
					int i = 0;
					while (i < data.length) {
						int j = i;
						while (j < data.length && data[j] != 0)
							j++;
						bf.append(' ');
						bf.append(new String(data, i, j - i, "UTF8"));
						if (j < data.length && data[j] == 0)
							j++;
						i = j;
					}
				}
				bf.append('\n');
				bf_line_cnt++;
			} catch (UnsupportedEncodingException x) {
				x.printStackTrace();
			}
		}
	}

	@Override
	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		if (memento == null)
			this.memento = XMLMemento.createWriteRoot("EDCTRACEVIEW"); //$NON-NLS-1$
		else
			this.memento = memento;

		Preferences p = getViewPreferences(); // never returns null
		this.memento.putBoolean(FILTER_HEARTBEATS, p.getBoolean(FILTER_HEARTBEATS, true));
		this.memento.putBoolean(REUSE_TABS, p.getBoolean(REUSE_TABS, true));
	}

	@Override
	public void saveState(IMemento memento) {
		if (this.memento == null || memento == null)
			return;
		this.memento.putString(FILTER_HEARTBEATS, filterAction.isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
		this.memento.putString(REUSE_TABS, reuseAction.isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
		memento.putMemento(this.memento);

		saveViewPreferences();
	}
	
	private void saveViewPreferences() {
		Preferences preferences = getViewPreferences();
		preferences.putBoolean(FILTER_HEARTBEATS, this.memento.getBoolean(FILTER_HEARTBEATS).booleanValue());
		preferences.putBoolean(REUSE_TABS, this.memento.getBoolean(REUSE_TABS).booleanValue());
		try {
			preferences.flush();
		} catch (BackingStoreException e) {
			// empty
		}
	}

	private Preferences getViewPreferences() {
		return EDCDebugger.getPrefs(EDCDebugUI.PLUGIN_ID);
	}

	@Override
	public void createPartControl(Composite parent) {
		this.parent = parent;
		
		createActions();
		
		Protocol.invokeAndWait(new Runnable() {
			public void run() {
				IChannel[] arr = Protocol.getOpenChannels();
				for (IChannel c : arr)
					onChannelOpen(c);
				Protocol.addChannelOpenListener(TraceView.this);
			}
		});
		if (tab2page.size() == 0)
			hideTabs();
	}
	
	private void createActions() {
		IToolBarManager toolbarManager = getViewSite().getActionBars().getToolBarManager();
		
		clearTabAction = new Action(null) {
			public void run() {
				Page currentPage = getCurrentPage();
				if (currentPage != null) {
					currentPage.text.setText(""); //$NON-NLS-1$
				}
			}
		};

		clearTabAction.setToolTipText("Clear the current tab");
		clearTabAction.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EDCDebugUI.PLUGIN_ID,
			"/icons/etool16/clear_tab.gif")); //$NON-NLS-1$
		
		clearTabAction.setDisabledImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EDCDebugUI.PLUGIN_ID,
			"/icons/dtool16/clear_tab.gif")); //$NON-NLS-1$

		toolbarManager.add(clearTabAction);

		closeTabAction = new Action(null) {
			public void run() {
				Page currentPage = getCurrentPage();
				if (currentPage != null) {
					currentPage.dispose();
				}
			}
		};

		closeTabAction.setToolTipText("Close the current tab");
		closeTabAction.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EDCDebugUI.PLUGIN_ID,
			"/icons/etool16/close_tab.gif")); //$NON-NLS-1$
		
		closeTabAction.setDisabledImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EDCDebugUI.PLUGIN_ID,
			"/icons/dtool16/close_tab.gif")); //$NON-NLS-1$

		toolbarManager.add(closeTabAction);

		exportAction = new Action(null) {
			public void run() {
				Page currentPage = getCurrentPage();
				if (currentPage != null) {
					handleExport(currentPage);
				}
			}
		};

		exportAction.setToolTipText("Export Log");
		exportAction.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EDCDebugUI.PLUGIN_ID,
			"/icons/etool16/export_log.gif")); //$NON-NLS-1$
		
		exportAction.setDisabledImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EDCDebugUI.PLUGIN_ID,
			"/icons/dtool16/export_log.gif")); //$NON-NLS-1$

		toolbarManager.add(exportAction);
		
		IMenuManager mgr = getViewSite().getActionBars().getMenuManager();

		filterAction = new Action("Filter heartbeats") { //$NON-NLS-1$
			public void run() {
				memento.putString(FILTER_HEARTBEATS, isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
			}
		};
		filterAction.setChecked(memento.getString(FILTER_HEARTBEATS).equals("true")); //$NON-NLS-1$

		mgr.add(filterAction);

		reuseAction = new Action("Reuse tab for channel") { //$NON-NLS-1$
			public void run() {
				memento.putString(REUSE_TABS, isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
			}
		};
		reuseAction.setChecked(memento.getString(REUSE_TABS).equals("true")); //$NON-NLS-1$

		mgr.add(reuseAction);
	}
	
	private Page getCurrentPage() {
		if (tabs != null) {
			int index = tabs.getSelectionIndex();
			if (index >= 0) {
				return tab2page.get(tabs.getSelection()[0]);
			}
		}
		return null;
	}

	@Override
	public void setFocus() {
		if (tabs != null)
			tabs.setFocus();
	}

	@Override
	public void dispose() {
		saveViewPreferences();
		
		final Page[] pages = tab2page.values().toArray(new Page[tab2page.size()]);
		Protocol.invokeAndWait(new Runnable() {
			public void run() {
				Protocol.removeChannelOpenListener(TraceView.this);
				for (Page p : pages)
					p.channel.removeTraceListener(p);
			}
		});
		for (Page p : pages)
			p.dispose();
		assert tab2page.isEmpty();
		if (tabs != null) {
			tabs.dispose();
			tabs = null;
		}
		if (no_data != null) {
			no_data.dispose();
			no_data = null;
		}
		super.dispose();
	}

	public void onChannelOpen(final IChannel channel) {
		if (!(channel instanceof AbstractChannel))
			return;
		AbstractChannel c = (AbstractChannel) channel;
		
		if (memento.getBoolean(REUSE_TABS)) {
			// see if the same channel is being opened again.  if so just clear
			// and reuse it.
			for (final Page page : tab2page.values()) {
				if (page.channel.getRemotePeer().equals(channel.getRemotePeer())) {
					c.addTraceListener(page);

					getSite().getShell().getDisplay().asyncExec(new Runnable() {
						public void run() {
							showTabs();

							// select the new tab automatically
							tabs.setSelection(page.tab);
							updateCloseAction();
						}
					});
					
					return;
				}
			}
		}

		IPeer rp = c.getRemotePeer();
		final String name = rp.getName();
		final String host = rp.getAttributes().get(IPeer.ATTR_IP_HOST);
		final String port = rp.getAttributes().get(IPeer.ATTR_IP_PORT);

		final Page p = new Page(c);
		c.addTraceListener(p);

		getSite().getShell().getDisplay().asyncExec(new Runnable() {
			public void run() {
				showTabs();
				p.tab = new TabItem(tabs, SWT.NONE);
				tab2page.put(p.tab, p);
				String title = name;
				if (host != null) {
					title += ", " + host;
					if (port != null) {
						title += ":" + port;
					}
				}
				p.tab.setText(title);
				p.text = new Text(tabs, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.MULTI);
				p.tab.setControl(p.text);
				p.text.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
				
				// select the new tab automatically
				tabs.setSelection(p.tab);
				updateCloseAction();
			}
		});
	}

	private void showTabs() {
		boolean b = false;
		if (no_data != null) {
			no_data.dispose();
			no_data = null;
			b = true;
		}
		if (tabs == null) {
			tabs = new TabFolder(parent, SWT.NONE);
			tabs.addSelectionListener(new SelectionListener() {
				
				public void widgetSelected(SelectionEvent e) {
					updateCloseAction();
				}
				
				public void widgetDefaultSelected(SelectionEvent e) {
				}
			});
			
			b = true;
		}
		if (b)
			parent.layout();
		
		clearTabAction.setEnabled(true);
		closeTabAction.setEnabled(true);
		exportAction.setEnabled(true);
	}

	private void updateCloseAction() {
		// disable the close action if the current tab
		// has an active channel so people don't accidentally
		// close it and have no way to get it back.
		Page page = getCurrentPage();
		if (page != null) {
			closeTabAction.setEnabled(page.channel.getState() == IChannel.STATE_CLOSED);
		}
	}

	private void hideTabs() {
		boolean b = false;
		if (tabs != null) {
			tabs.dispose();
			tabs = null;
			b = true;
		}
		if (!parent.isDisposed()) {
			if (no_data == null) {
				no_data = new Label(parent, SWT.NONE);
				no_data.setText("No open communication channels at this time.");
				b = true;
			}
			if (b)
				parent.layout();
		}
		
		clearTabAction.setEnabled(false);
		closeTabAction.setEnabled(false);
		exportAction.setEnabled(false);
	}

	private void handleExport(Page currentPage) {
		FileDialog dialog = new FileDialog(getViewSite().getShell(), SWT.SAVE);
		dialog.setFilterExtensions(new String[] {"*.log"}); //$NON-NLS-1$
		String path = dialog.open();
		if (path != null) {
			if (path.indexOf('.') == -1 && !path.endsWith(".log")) //$NON-NLS-1$
				path += ".log"; //$NON-NLS-1$
			File outputFile = new Path(path).toFile();
			if (outputFile.exists()) {
				String message = "File exists.  Would you like to overwrite it?";
				if (!MessageDialog.openQuestion(getViewSite().getShell(), "Export Log", message))
					return;
			}

			Writer out = null;
			try {
				out = new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8"); //$NON-NLS-1$
			} catch (IOException ex) {
				return;
			}
			Reader in = new StringReader(currentPage.text.getText());
			copy(in, out);
			try {
				if (in != null)
					in.close();
			} catch (IOException e1) { // do nothing
			}
			try {
				if (out != null)
					out.close();
			} catch (IOException e1) { // do nothing
			}
		}
	}

	private void copy(Reader input, Writer output) {
		String line;
		BufferedReader reader = new BufferedReader(input);
		BufferedWriter writer = new BufferedWriter(output);
		try {
			while (reader.ready() && ((line = reader.readLine()) != null)) {
				writer.write(line);
				writer.newLine();
			}
		} catch (IOException e) { // do nothing
		} finally {
			try {
				if (reader != null)
					reader.close();
			} catch (IOException e1) { // do nothing
			}
			try
			{
				if (writer != null)
					writer.close();
			} catch (IOException e1) { // do nothing
			}
		}
	}
}
