/*******************************************************************************
 * Copyright (c) 2003, 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.server.ui.internal.view.servers;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.viewers.*;

import org.eclipse.wst.server.core.*;
import org.eclipse.wst.server.core.internal.Server;
import org.eclipse.wst.server.core.util.PublishAdapter;
import org.eclipse.wst.server.ui.internal.Trace;
import org.eclipse.wst.server.ui.internal.viewers.BaseContentProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.PlatformUI;
/**
 * Tree view showing servers and their associations.
 */
public class ServerTableViewer extends TreeViewer {
	protected static final String ROOT = "root";
	protected static Color color;
	protected static Font font;
	protected Clipboard clipboard;

	protected IServerLifecycleListener serverResourceListener;
	protected IPublishListener publishListener;
	protected IServerListener serverListener;

	protected static Object deletedElement = null;

	// servers that are currently publishing and starting
	protected static Set<String> publishing = new HashSet<String>(4);
	protected static Set<String> starting = new HashSet<String>(4);

	protected ServerTableLabelProvider labelProvider;
	//protected ISelectionListener dsListener;

	protected ServersView view;

	protected boolean animationActive = false;
	protected boolean stopAnimation = false;

	public class ServerContentProvider extends BaseContentProvider implements ITreeContentProvider {
		public Object[] getElements(Object element) {
			List<IServer> list = new ArrayList<IServer>();
			IServer[] servers = ServerCore.getServers();
			if (servers != null) {
				int size = servers.length;
				for (int i = 0; i < size; i++) {
					if (!((Server)servers[i]).isPrivate())
						list.add(servers[i]);
				}
			}
			return list.toArray();
		}

		public Object[] getChildren(Object element) {
			if (element instanceof ModuleServer) {
				ModuleServer ms = (ModuleServer) element;
				try {
					IModule[] children = ms.server.getChildModules(ms.module, null);
					int size = children.length;
					ModuleServer[] ms2 = new ModuleServer[size];
					for (int i = 0; i < size; i++) {
						int size2 = ms.module.length;
						IModule[] module = new IModule[size2 + 1];
						System.arraycopy(ms.module, 0, module, 0, size2);
						module[size2] = children[i];
						ms2[i] = new ModuleServer(ms.server, module);
					}
					return ms2;
				} catch (Exception e) {
					return null;
				}
			}
			
			IServer server = (IServer) element;
			IModule[] modules = server.getModules(); 
			int size = modules.length;
			ModuleServer[] ms = new ModuleServer[size];
			for (int i = 0; i < size; i++) {
				ms[i] = new ModuleServer(server, new IModule[] { modules[i] });
			}
			return ms;
		}

		public Object getParent(Object element) {
			if (element instanceof ModuleServer) {
				ModuleServer ms = (ModuleServer) element;
				return ms.server;
			}
			return null;
		}

		public boolean hasChildren(Object element) {
			if (element instanceof ModuleServer) {
				// Check if the module server has child modules.
				ModuleServer curModuleServer = (ModuleServer)element;
				IServer curServer = curModuleServer.server;
				IModule[] curModule = curModuleServer.module;
				if (curServer != null &&  curModule != null) {
					IModule[] curChildModule = curServer.getChildModules(curModule, null);
					if (curChildModule != null && curChildModule.length > 0)
						return true;
					
					return false;
				}
				
				return false;
			}
			
			IServer server = (IServer) element;
			return server.getModules().length > 0;
		}
	}

	protected void startThread() {
		if (animationActive)
			return;
		
		stopAnimation = false;
		
		final Display display = getTree().getDisplay();
		final int SLEEP = 200;
		final Runnable[] animator = new Runnable[1];
		animator[0] = new Runnable() {
			public void run() {
				if (!stopAnimation) {
					try {
						labelProvider.animate();
						
						int size = 0;
						String[] servers;
						synchronized (starting) {
							size = starting.size();
							servers = new String[size];
							starting.toArray(servers);
						}
						
						for (int i = 0; i < size; i++) {
							IServer server = ServerCore.findServer(servers[i]);
							if (server != null && getTree() != null && !getTree().isDisposed())
								updateAnimation(server);
						}
					} catch (Exception e) {
						if (Trace.FINEST) {
							Trace.trace(Trace.STRING_FINEST, "Error in Servers view animation", e);
						}
					}
					display.timerExec(SLEEP, animator[0]);
				}
			}
		};
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				display.timerExec(SLEEP, animator[0]);
			}
		});
	}

	protected void stopThread() {
		stopAnimation = true;
	}

	/**
	 * ServerTableViewer constructor comment.
	 * 
	 * @param view the view 
	 * @param tree the tree
	 */
	public ServerTableViewer(final ServersView view, final Tree tree) {
		super(tree);
		this.view = view;
		clipboard = new Clipboard(tree.getDisplay());
	}
	
	protected void initialize() {
		ColumnViewerToolTipSupport.enableFor(this);
		setContentProvider(new ServerContentProvider());
		labelProvider = new ServerTableLabelProvider();		
		setLabelProvider(labelProvider);		
		
		setComparator(new ServerViewerComparator(labelProvider));
		
		setInput(ROOT);
		addListeners();
		
		/*dsListener = new ISelectionListener() {
			public void selectionChanged(IWorkbenchPart part, ISelection selection) {
				if (!(selection instanceof IStructuredSelection))
					return;
				IStructuredSelection sel = (IStructuredSelection) selection;
				final Object obj = sel.getFirstElement();
				IProject proj = null;
				if (obj instanceof IResource) {
					IResource res = (IResource) obj;
					proj = res.getProject();
				}
				if (proj == null && obj != null) {
					try {
						IResource res = (IResource) Platform.getAdapterManager().getAdapter(obj, IResource.class);
						if (res != null)
							proj = res.getProject();
					} catch (Exception e) {
						// ignore
					}
				}
				if (proj != null) {
					final IProject project = proj;
					final IModule module = ServerUtil.getModule(project);
					Display.getDefault().asyncExec(new Runnable() {
						public void run() {
							if (getTree() == null || getTree().isDisposed())
								return;

							IServer defaultServer = null;
							if (module != null)
								defaultServer = ServerCore.getDefaultServer(module);
							
							IServer oldDefaultServer = labelProvider.getDefaultServer();
							if ((oldDefaultServer == null && defaultServer == null)
									|| (oldDefaultServer != null && oldDefaultServer.equals(defaultServer)))
								return;
							labelProvider.setDefaultServer(defaultServer);
							
							if (oldDefaultServer != null)
								refresh(oldDefaultServer);
							if (defaultServer != null)
								refresh(defaultServer);
						}
					});
				}
			}
		};
		view.getViewSite().getPage().addSelectionListener(dsListener);*/
		
		if (color == null) {
			Display display = getControl().getDisplay();
			color = display.getSystemColor(SWT.COLOR_DARK_GRAY);
			FontData[] fd = getControl().getFont().getFontData();
			int size = fd.length;
			for (int i = 0; i < size; i++)
				fd[i].setStyle(SWT.ITALIC);
			font = new Font(display, fd);
		}
	}

	protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
		Object[] obj = event.getElements();
		if (obj == null)
			refresh(true);
		else {
			obj = adaptLabelChangeObjects(obj);
			int size = obj.length;
			for (int i = 0; i < size; i++)
				update(obj[i], null);
		}
	}

	/**
	 * Resort the table based on field.
	 * 
	 * @param column the column being updated
	 * @param col
	 */
	protected void resortTable(final TreeColumn column, int col) {
		ServerViewerComparator sorter = (ServerViewerComparator) getComparator();
		
		if (col == sorter.getTopPriority())
			sorter.reverseTopPriority();
		else
			sorter.setTopPriority(col);
		
		PlatformUI.getWorkbench().getDisplay().asyncExec(
			new Runnable() {
				public void run() {
					refresh();
					updateDirectionIndicator(column);
				}
			});
	}

	/**
	 * Update the direction indicator as column is now the primary column.
	 * 
	 * @param column
	 */
	protected void updateDirectionIndicator(TreeColumn column) {
		getTree().setSortColumn(column);
		if (((ServerViewerComparator) getComparator()).getTopPriorityDirection() == ServerViewerComparator.ASCENDING)
			getTree().setSortDirection(SWT.UP);
		else
			getTree().setSortDirection(SWT.DOWN);
	}

	protected Object[] adaptLabelChangeObjects(Object[] obj) {
		if (obj == null)
			return obj;
		
		List<Object> list = new ArrayList<Object>();
		int size = obj.length;
		for (int i = 0; i < size; i++) {
			if (obj[i] instanceof IModule) {
				list.add(obj[i]);
			} else if (obj[i] instanceof IServer) {
				list.add(obj[i]);
			} else if (obj[i] instanceof ModuleServer) {
				list.add(obj[i]);
			} else if (obj[i] instanceof IProject) {
				IProject proj = (IProject) obj[i];

				List<Object> list2 = new ArrayList<Object>();
				getTreeChildren(list2, view.treeTable);
				
				Iterator iterator = list2.iterator();
				while (iterator.hasNext()) {
					Object o = iterator.next();
					if (o instanceof ModuleServer) {
						ModuleServer ms = (ModuleServer) o;
						if (proj.equals(ms.module[ms.module.length - 1].getProject()))
							list.add(ms);
					}
				}
			}
		}
		
		Object[] o = new Object[list.size()];
		list.toArray(o);
		return o;
	}

	private void getTreeChildren(List<Object> list, Widget widget) {
		Item[] items = getChildren(widget);
		for (int i = 0; i < items.length; i++) {
			Item item = items[i];
			Object data = item.getData();
			if (data != null)
				list.add(data);
			
			if (getExpanded(item)) {
				// only recurse if it is expanded - if
				// not then the children aren't visible
				getTreeChildren(list, item);
			}
		}
	}

	protected void addListeners() {
		serverResourceListener = new IServerLifecycleListener() {
			public void serverAdded(IServer server) {
				addServer(server);
				server.addServerListener(serverListener);
				((Server) server).addPublishListener(publishListener);
			}
			public void serverChanged(IServer server) {
				refreshServer(server);
			}
			public void serverRemoved(IServer server) {
				removeServer(server);
				server.removeServerListener(serverListener);
				((Server) server).removePublishListener(publishListener);
			}
		};
		ServerCore.addServerLifecycleListener(serverResourceListener);
		
		publishListener = new PublishAdapter() {
			public void publishStarted(IServer server) {
				handlePublishChange(server, true);
			}
			
			public void publishFinished(IServer server, IStatus status) {
				handlePublishChange(server, false);
			}
		};
		
		serverListener = new IServerListener() {
			public void serverChanged(ServerEvent event) {
				if (event == null)
					return;
				
				int eventKind = event.getKind();
				IServer server = event.getServer();
				if ((eventKind & ServerEvent.SERVER_CHANGE) != 0) {
					// server change event
					if ((eventKind & ServerEvent.STATE_CHANGE) != 0) {
						refreshServer(server);
						int state = event.getState();
						String id = server.getId();
						if (state == IServer.STATE_STARTING || state == IServer.STATE_STOPPING) {
							boolean startThread = false;
							synchronized (starting) {
								if (!starting.contains(id)) {
									if (starting.isEmpty())
										startThread = true;
									starting.add(id);
								}
							}
							if (startThread)
								startThread();
						} else {
							boolean stopThread = false;
							synchronized (starting) {
								if (starting.contains(id)) {
									starting.remove(id);
									if (starting.isEmpty())
										stopThread = true;
								}
							}
							if (stopThread)
								stopThread();
						}
					} else
						refreshServer(server);
				} else if ((eventKind & ServerEvent.MODULE_CHANGE) != 0) {
					// module change event
					if ((eventKind & ServerEvent.STATE_CHANGE) != 0 || (eventKind & ServerEvent.PUBLISH_STATE_CHANGE) != 0) {
						refreshServer(server);
					}
				}
			}
		};
		
		// add listeners to servers
		IServer[] servers = ServerCore.getServers();
		if (servers != null) {
			int size = servers.length;
			for (int i = 0; i < size; i++) {
				servers[i].addServerListener(serverListener);
				((Server) servers[i]).addPublishListener(publishListener);
			}
		}
	}

	/**
	 * @param server
	 * @deprecated With the introduction of the CNF this method shouldn't be called
	 */
	protected void refreshServer(final IServer server) {
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				try {
					refresh(server);
					ISelection sel = ServerTableViewer.this.getSelection();
					ServerTableViewer.this.setSelection(sel);
				} catch (Exception e) {
					// ignore
				}
			}
		});
	}

	protected void handleDispose(DisposeEvent event) {
		stopThread();
		//if (dsListener != null)
		//	view.getViewSite().getPage().removeSelectionListener(dsListener);
		
		ServerCore.removeServerLifecycleListener(serverResourceListener);
		
		// remove listeners from server
		IServer[] servers = ServerCore.getServers();
		if (servers != null) {
			int size = servers.length;
			for (int i = 0; i < size; i++) {
				if (serverListener != null)
					servers[i].removeServerListener(serverListener);
				if (publishListener != null)
					((Server) servers[i]).removePublishListener(publishListener);
			}
		}
		
		clipboard.dispose();
		
		super.handleDispose(event);
	}

	/**
	 * Called when the publish state changes.
	 * @param server org.eclipse.wst.server.core.IServer
	 */
	protected void handlePublishChange(IServer server, boolean isPublishing) {
		String serverId = server.getId();
		if (isPublishing)
			publishing.add(serverId);
		else
			publishing.remove(serverId);
	
		refreshServer(server);
	}
	
	/**
	 * 
	 */
	protected void handleServerModulesChanged(IServer server2) {
		if (server2 == null)
			return;

		IServer[] servers = ServerCore.getServers();
		if (servers != null) {
			int size = servers.length;
			for (int i = 0; i < size; i++) {
				if (server2.equals(servers[i]))
					refresh(servers[i]);
			}
		}
	}
	
	/**
	 * Called when an element is added.
	 * @param server org.eclipse.wst.server.core.IServer
	 */
	protected void handleServerResourceAdded(IServer server) {
		add(null, server);
	}
	
	/*protected void handleServerResourceAdded(IServerConfiguration configuration) {
		configurationChange(configuration, true);
	}*/
	
	/**
	 * Called when an element is changed.
	 * @param server org.eclipse.wst.server.core.IServer
	 */
	protected void handleServerResourceChanged(IServer server) {
		refresh(server);
	}
	
	/*protected void handleServerResourceChanged(IServerConfiguration configuration) {
		IServer[] servers = ServerCore.getServers();
		if (servers != null) {
			int size = servers.length;
			for (int i = 0; i < size; i++) {
				IServerConfiguration config = servers[i].getServerConfiguration();
				if (configuration.equals(config))
					refresh(servers[i]);
			}
		}
	}*/
	
	/**
	 * Called when an element is removed.
	 * @param server org.eclipse.wst.server.core.IServer
	 */
	protected void handleServerResourceRemoved(IServer server) {
		remove(server);

		String serverId = server.getId();
		publishing.remove(serverId);

		view.getViewSite().getActionBars().getStatusLineManager().setMessage(null, null);
	}

	/*protected void handleServerResourceRemoved(IServerConfiguration configuration) {
		configurationChange(configuration, false);
	}*/

	protected void addServer(final IServer server) {
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				add(ROOT, server);
			}
		});
	}

	protected void removeServer(final IServer server) {
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				remove(server);
			}
		});
	}

	public void doUpdateItem(Widget widget, Object element, boolean fullMap) {
		if (widget instanceof TreeItem && color != null) {
			TreeItem item = (TreeItem) widget;
			if (element instanceof ModuleServer) {
				ModuleServer ms = (ModuleServer) element;
				IModule m = ms.module[ms.module.length-1];
				if (m.isExternal())
					item.setForeground(color);
				else
					item.setForeground(null);
				if (ms.server.getModulePublishState(ms.module) != IServer.PUBLISH_STATE_NONE)
					item.setFont(0, font);
				else
					item.setFont(0, null);
			}
		}
		super.doUpdateItem(widget, element, fullMap);
	}

	protected void updateAnimation(IServer server) {
		try {
			Widget widget = doFindItem(server);
			TreeItem item = (TreeItem) widget;
			item.setText(1, labelProvider.getColumnText(server, 1));
			item.setImage(1, labelProvider.getColumnImage(server, 1));
		} catch (Exception e) {
			if (Trace.WARNING) {
				Trace.trace(Trace.STRING_WARNING, "Error in optimized animation", e);
			}
		}
	}
}