/*******************************************************************************
 * Copyright (c) 2002, 2018 IBM Corporation and others.
 *
 * 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 - Initial API and implementation
 *******************************************************************************/

package org.eclipse.core.tools.resources;

import java.util.*;
import org.eclipse.core.internal.dtree.AbstractDataTreeNode;
import org.eclipse.core.internal.dtree.DataTreeNode;
import org.eclipse.core.internal.resources.*;
import org.eclipse.core.internal.watson.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.tools.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;

/**
 * A spy view that shows detailed information about the workspace's element tree,
 * including space usage for the tree, and all resource metadata including markers,
 * sync info, and session properties.
 */
public class ElementTreeView extends SpyView implements IResourceChangeListener {

	class UpdateAction extends Action {

		class Counter implements Comparable<Counter> {
			int count = 1;
			String name;

			Counter(String name) {
				this.name = name;
			}

			void add() {
				count++;
			}

			@Override
			public int compareTo(Counter o) {
				return o.getCount() - count;
			}

			int getCount() {
				return count;
			}

			String getName() {
				return name;
			}

		}

		int layerCount;
		int markerCount;
		int markerMemory;
		int nodeCount;
		int nonIdenticalStrings;
		int phantomCount;
		int hiddenCount;

		int resourceCount;
		DeepSize sessionPropertyMemory;
		List<Counter> sortedList;
		int stringMemory;

		final Map<String, Counter> strings = new HashMap<>();
		int syncInfoCount;
		int syncInfoMemory;
		int teamPrivateCount;

		//tree memory includes memory for strings and child array
		int treeNodeMemory;
		Workspace workspace = (Workspace) ResourcesPlugin.getWorkspace();

		UpdateAction() {
			super("Update view");
			this.setToolTipText("Update");
			this.setImageDescriptor(ImageDescriptor.createFromURLSupplier(true, () -> ElementTreeView.class.getResource("/icons/refresh.gif")));
		}

		void addToStringCount(String name) {
			if (name == null)
				return;
			//want to track the number of non-identical strings
			if (!DeepSize.ignore(name)) {
				nonIdenticalStrings++;
				//can't call sizeof because it will call isUnique again and weed out duplicates
				stringMemory += basicSizeof(name);

				//now want to count the number of duplicate equal but non-identical strings
				Counter counter = strings.get(name);
				if (counter == null)
					strings.put(name, new Counter(name));
				else
					counter.add();
			}
		}

		void analyzeStrings() {
			sortedList = new ArrayList<>(strings.values());
			sortedList.sort(null);
		}

		void analyzeTrees() {
			// count the number of layers and the number of nodes
			// at each layer
			ElementTree tree = SpySupport.getOldestTree();
			for (this.layerCount = 0; tree != null; tree = tree.getParent()) {
				layerCount++;
				visit(tree);
			}
		}

		int basicSizeof(Map<?, ?> map) {
			if (map == null)
				return 0;

			//formula taken from BundleStats
			int count = (int) Math.round(44 + (16 + (map.size() * 1.25 * 4)) + (24 * map.size()));

			for (Map.Entry<?, ?> entry : map.entrySet()) {
				count += sizeof(entry.getKey());
				count += sizeof(entry.getValue());
			}
			return count;
		}

		int basicSizeof(MarkerAttributeMap<?> markerMap) {
			int count = DeepSize.OBJECT_HEADER_SIZE + 8;//object header plus two slots
			Object[] elements = SpySupport.getElements(markerMap);
			if (elements != null) {
				count += DeepSize.ARRAY_HEADER_SIZE + 4 * elements.length;
				for (int i = 0; i < elements.length; i++)
					count += sizeof(elements[i]);
			}
			return count;
		}

		int basicSizeof(MarkerInfo info) {
			int count = DeepSize.OBJECT_HEADER_SIZE + 24;//object plus slots
			count += sizeof(info.getType());
			count += sizeof(info.getAttributes(false));
			return count;
		}

		int basicSizeof(MarkerSet markerSet) {
			if (markerSet == null)
				return 0;
			int count = DeepSize.OBJECT_HEADER_SIZE + 8;//object size plus two slots
			IMarkerSetElement[] elements = SpySupport.getElements(markerSet);
			if (elements != null) {
				count += DeepSize.ARRAY_HEADER_SIZE + 4 * elements.length;//size of elements array object
				for (int i = 0; i < elements.length; i++)
					if (elements[i] != null)
						count += sizeof(elements[i]);
			}
			return count;
		}

		int basicSizeof(String str) {
			//String object has four slots, plus char[] object, plus two bytes per character
			return 16 + DeepSize.OBJECT_HEADER_SIZE + DeepSize.ARRAY_HEADER_SIZE + 2 * str.length();
		}

		void countResources() {
			// count the number of resources
			resourceCount = 0;
			markerCount = 0;
			teamPrivateCount = 0;
			phantomCount = 0;
			hiddenCount = 0;
			syncInfoCount = 0;
			IElementContentVisitor visitor = (tree, requestor, elementContents) -> {
				ResourceInfo info = (ResourceInfo) elementContents;
				if (info == null)
					return true;
				resourceCount++;
				if (info.isSet(ICoreConstants.M_TEAM_PRIVATE_MEMBER))
					teamPrivateCount++;
				if (info.isSet(ICoreConstants.M_PHANTOM))
					phantomCount++;
				if (info.isSet(ICoreConstants.M_HIDDEN))
					hiddenCount++;
				MarkerSet markers = info.getMarkers();
				if (markers != null)
					markerCount += markers.size();
				Map<QualifiedName, Object> syncInfo = SpySupport.getSyncInfo(info);
				if (syncInfo != null)
					syncInfoCount += syncInfo.size();
				return true;
			};
			new ElementTreeIterator(workspace.getElementTree(), Path.ROOT).iterate(visitor);
		}

		void reset() {
			resourceCount = 0;
			teamPrivateCount = 0;
			phantomCount = 0;
			hiddenCount = 0;
			layerCount = 0;
			nodeCount = 0;

			treeNodeMemory = 0;
			stringMemory = 0;
			markerMemory = 0;
			syncInfoMemory = 0;
			sessionPropertyMemory = new DeepSize();

			strings.clear();
			DeepSize.reset();
			sortedList = null;
			nonIdenticalStrings = 0;
		}

		@Override
		public void run() {
			super.run();
			reset();
			countResources();
			analyzeTrees();
			analyzeStrings();
			updateTextView();
			reset();
		}

		int sizeof(AbstractDataTreeNode node) {
			int count = DeepSize.OBJECT_HEADER_SIZE;//empty object
			if (node instanceof DataTreeNode) {
				//count memory for data
				count += 4;//reference to data
				Object data = ((DataTreeNode) node).getData();
				if (data instanceof ResourceInfo) {
					count += sizeof((ResourceInfo) data);
				}
			}
			//name
			count += 4;//reference to name
			//NOTE: space for name string is counted separately (see addToStringCount)

			//children
			count += 4;//reference to child array
			AbstractDataTreeNode[] children = node.getChildren();
			if (children != null && !DeepSize.ignore(children)) {
				count += DeepSize.ARRAY_HEADER_SIZE + (4 * children.length);//object header plus slots
			}
			return count;
		}

		/**
		 * All sizeof tests should go through this central method to weed out
		 * duplicates.
		 */
		int sizeof(Object object) {
			if (object == null || DeepSize.ignore(object))
				return 0;
			if (object instanceof String)
				return basicSizeof((String) object);
			if (object instanceof byte[])
				return DeepSize.ARRAY_HEADER_SIZE + ((byte[]) object).length;
			if (object instanceof MarkerAttributeMap)
				return basicSizeof((MarkerAttributeMap<?>) object);
			if (object instanceof MarkerInfo)
				return basicSizeof((MarkerInfo) object);
			if (object instanceof MarkerSet)
				return basicSizeof((MarkerSet) object);
			if (object instanceof Integer)
				return DeepSize.OBJECT_HEADER_SIZE + 4;
			if (object instanceof Map)
				return basicSizeof((Map<?, ?>) object);
			if (object instanceof QualifiedName) {
				QualifiedName name = (QualifiedName) object;
				return 20 + sizeof(name.getQualifier()) + sizeof(name.getLocalName());
			}
			// unknown -- use deep size
			return 0;
		}

		int sizeof(ResourceInfo resourceInfo) {
			//object header plus all slots
			int count = DeepSize.OBJECT_HEADER_SIZE + (11 * 4);

			//markers
			markerMemory += sizeof(resourceInfo.getMarkers());

			//sync info
			syncInfoMemory += sizeof(SpySupport.getSyncInfo(resourceInfo));

			//session properties
			sessionPropertyMemory.deepSize(SpySupport.getSessionProperties(resourceInfo));

			if (resourceInfo.getClass() == RootInfo.class) {
				count += 4;//ref to property store
			}
			if (resourceInfo.getClass() == ProjectInfo.class) {
				count += 4 * 4;//four more slots
			}
			return count;
		}

		/**
		 * Sorts a set of entries whose keys are strings and values are Integer
		 * objects, in decreasing order by the integer value.
		 */
		private List<Map.Entry<Object, Integer>> sortEntrySet(Set<Map.Entry<Object, Integer>> set) {
			List<Map.Entry<Object, Integer>> result = new ArrayList<>();
			result.addAll(set);
			result.sort((arg0, arg1) -> arg1.getValue().intValue() - arg0.getValue().intValue());
			return result;
		}

		void updateTextView() {
			final StringBuilder buffer = new StringBuilder();
			buffer.append("Total resource count: " + prettyPrint(resourceCount) + "\n");
			buffer.append("\tTeam private: " + prettyPrint(teamPrivateCount) + "\n");
			buffer.append("\tPhantom: " + prettyPrint(phantomCount) + "\n");
			buffer.append("\tHidden: " + prettyPrint(hiddenCount) + "\n");
			buffer.append("\tMarkers: " + prettyPrint(markerCount) + "\n");
			buffer.append("\tSyncInfo: " + prettyPrint(syncInfoCount) + "\n");
			buffer.append("Number of layers: " + layerCount + "\n");
			buffer.append("Number of nodes: " + prettyPrint(nodeCount) + "\n");
			buffer.append("Number of non-identical strings: " + prettyPrint(nonIdenticalStrings) + "\n");

			int sessionSize = sessionPropertyMemory.getSize();
			int totalMemory = treeNodeMemory + stringMemory + markerMemory + syncInfoMemory + sessionSize;
			buffer.append("Total memory used by nodes: " + prettyPrint(totalMemory) + "\n");
			buffer.append("\tNodes and ResourceInfo: " + prettyPrint(treeNodeMemory) + "\n");
			buffer.append("\tStrings: " + prettyPrint(stringMemory) + "\n");
			buffer.append("\tMarkers: " + prettyPrint(markerMemory) + "\n");
			buffer.append("\tSync info: " + prettyPrint(syncInfoMemory) + "\n");
			buffer.append("\tSession properties: " + prettyPrint(sessionSize) + "\n");
			//breakdown of session property size by class
			List<Map.Entry<Object, Integer>> sortedEntries = sortEntrySet(sessionPropertyMemory.getSizes().entrySet());
			for (Map.Entry<Object, Integer> entry : sortedEntries) {
				buffer.append("\t\t" + entry.getKey() + ": " + prettyPrint(entry.getValue().intValue()) + "\n");
			}

			int max = 20;
			int savings = 0;
			buffer.append("The top " + max + " equal but non-identical strings are:\n");
			for (int i = 0; i < sortedList.size() && sortedList.get(i).getCount() > 1; i++) {
				Counter c = sortedList.get(i);
				if (i < max)
					buffer.append("\t" + c.getName() + "->" + prettyPrint(c.getCount()) + "\n");
				savings += ((c.getCount() - 1) * basicSizeof(c.getName()));
			}
			buffer.append("Potential savings of using unique strings: " + prettyPrint(savings) + "\n");

			//post changes to UI thread
			viewer.getControl().getDisplay().asyncExec(() -> {
				if (!viewer.getControl().isDisposed()) {
					IDocument doc = viewer.getDocument();
					doc.set(buffer.toString());
					viewer.setDocument(doc);
				}
			});
		}

		void visit(AbstractDataTreeNode node) {
			//			if ("CVS".equals(node.getName())) {
			//				System.out.println("here");
			//			}
			nodeCount++;
			addToStringCount(node.getName());
			treeNodeMemory += sizeof(node);
			AbstractDataTreeNode[] children = node.getChildren();
			for (int i = 0; i < children.length; i++)
				visit(children[i]);
		}

		void visit(ElementTree tree) {
			AbstractDataTreeNode node = org.eclipse.core.internal.dtree.SpySupport.getRootNode(tree.getDataTree());
			visit(node);
		}
	}

	private IAction updateAction;

	// The JFace widget used for showing the Element Tree info.
	protected TextViewer viewer;

	/**
	 * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	public void createPartControl(Composite parent) {

		viewer = new TextViewer(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.WRAP | SWT.READ_ONLY);
		viewer.setDocument(new Document());

		IActionBars bars = getViewSite().getActionBars();

		final GlobalAction clearOutputAction = new ClearTextAction(viewer.getDocument());
		clearOutputAction.registerAsGlobalAction(bars);

		final GlobalAction selectAllAction = new SelectAllAction(viewer);
		selectAllAction.registerAsGlobalAction(bars);

		IMenuManager barMenuManager = getViewSite().getActionBars().getMenuManager();
		updateAction = new UpdateAction();
		barMenuManager.add(updateAction);

		// Delete action shortcuts are not captured by the workbench
		// so we need our key binding service to handle Delete keystrokes for us

		this.viewer.getControl().addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.character == SWT.DEL)
					clearOutputAction.run();
			}
		});

		GlobalAction copyAction = new CopyTextSelectionAction(viewer);
		copyAction.registerAsGlobalAction(bars);

		bars.getToolBarManager().add(updateAction);
		bars.getToolBarManager().add(clearOutputAction);
		bars.updateActionBars();

		// creates a context menu with actions and adds it to the viewer control
		MenuManager menuMgr = new MenuManager();
		menuMgr.add(copyAction);
		menuMgr.add(clearOutputAction);
		Menu menu = menuMgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);

		// add the resource change listener
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);

		// populate the view with the initial data
		if (updateAction != null)
			updateAction.run();
	}

	/**
	 * @see org.eclipse.ui.IWorkbenchPart#dispose()
	 */
	@Override
	public void dispose() {
		super.dispose();
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
		updateAction = null;
	}

	String prettyPrint(int i) {
		StringBuilder buf = new StringBuilder();
		for (;;) {
			if (i < 1000) {
				String val = Integer.toString(i);
				//pad with zeros if necessary
				if (buf.length() > 0) {
					if (val.length() < 2)
						buf.append('0');
					if (val.length() < 3)
						buf.append('0');
				}
				buf.append(val);
				return buf.toString();
			}
			if (i < 1000000) {
				String val = Integer.toString(i / 1000);
				//pad with zeros if necessary
				if (buf.length() > 0) {
					if (val.length() < 2)
						buf.append('0');
					if (val.length() < 3)
						buf.append('0');
				}
				buf.append(val);
				buf.append(',');
				i = i % 1000;
				continue;
			}
			buf.append(Integer.toString(i / 1000000));
			buf.append(',');
			i = i % 1000000;
		}
	}

	/**
	 * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent)
	 */
	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		if (updateAction != null)
			updateAction.run();
	}
}
