/*******************************************************************************
 * Copyright (c) 2004, 2005 IBM Corporation 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:
 *     IBM - Initial API and implementation
 *******************************************************************************/

package org.eclipse.core.tools.runtime;

import java.util.*;
import org.eclipse.core.internal.preferences.EclipsePreferences;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.preferences.*;
import org.eclipse.core.tools.*;
import org.eclipse.jface.action.*;
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;
import org.osgi.service.prefs.BackingStoreException;

/**
 * Text view that dumps sizeof info and stats about the
 * Eclipse preferences tree.
 * 
 * @since 3.0
 */
public class PreferenceStatsView extends SpyView {

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

	private IAction updateAction;

	class UpdateAction extends Action {

		// number of nodes in the tree
		int nodeCount;
		// number of key/value pairs in the tree
		int kvCount;
		// number of nodes without key/value pairs
		int emptyNodes;
		// size of the tree
		int treeSize;
		// list of node with key/value pairs
		Set nonEmptyNodes;

		// root node
		IEclipsePreferences rootNode = Platform.getPreferencesService().getRootNode();

		UpdateAction() {
			super("Update view"); //$NON-NLS-1$
			this.setToolTipText("Update"); //$NON-NLS-1$
			this.setImageDescriptor(CoreToolsPlugin.createImageDescriptor("refresh.gif")); //$NON-NLS-1$
		}

		public void run() {
			super.run();
			reset();
			try {
				visitTree();
			} catch (BackingStoreException e) {
				e.printStackTrace();
			}
			updateTextView();
			reset();
		}

		void reset() {
			nodeCount = 0;
			kvCount = 0;
			emptyNodes = 0;
			treeSize = 0;
			nonEmptyNodes = new TreeSet();
		}

		int basicSizeof(IEclipsePreferences node) {
			if (node instanceof EclipsePreferences)
				return basicSizeof((EclipsePreferences) node);

			// name
			int count = sizeof(node.name());

			// key/value pairs
			try {
				String[] keys = node.keys();
				for (int i = 0; i < keys.length; i++) {
					count += sizeof(keys[i]);
					String value = node.get(keys[i], null);
					count += sizeof(value);
				}
			} catch (BackingStoreException e) {
				e.printStackTrace();
			}
			return count;
		}

		int calculateOldSize() {
			int count = 0;
			IPluginRegistry registry = Platform.getPluginRegistry();
			if (registry == null)
				return count;
			IPluginDescriptor[] descriptors = registry.getPluginDescriptors();
			if (descriptors == null)
				return count;
			for (int i = 0; i < descriptors.length; i++) {
				IPluginDescriptor desc = descriptors[i];
				//				if (desc.isPluginActivated())
				count += calculateOldSizeFor(desc.getUniqueIdentifier());
			}
			return count;
		}

		int calculateOldSizeFor(String pluginID) {
			int count = 0;
			// 12 for the object header + 4 for each field
			count += 12;

			// dirty boolean
			count += 4;

			// listener list
			// TODO
			count += 4;

			// Properties properties
			count += 4;
			IEclipsePreferences node = new InstanceScope().getNode(pluginID);
			if (node != null) {
				// add the key/value pairs
				// TODO rough estimate
				try {
					String[] keys = node.keys();
					for (int i = 0; i < keys.length; i++) {
						count += sizeof(keys[i]);
						String value = node.get(keys[i], null);
						count += sizeof(value);
					}
				} catch (BackingStoreException e) {
					e.printStackTrace();
				}
			}

			// Properties defaults
			count += 4;
			node = new DefaultScope().getNode(pluginID);
			if (node != null) {
				// add the key/value pairs
				// TODO rough estimate
				try {
					String[] keys = node.keys();
					for (int i = 0; i < keys.length; i++) {
						count += sizeof(keys[i]);
						String value = node.get(keys[i], null);
						count += sizeof(value);
					}
				} catch (BackingStoreException e) {
					e.printStackTrace();
				}
			}

			return count;
		}

		/*
		 * 12 for the object header
		 * 4 for each slot
		 */
		int basicSizeof(EclipsePreferences node) {
			int count = 12;

			// name
			count += 4;
			count += sizeof(node.name());

			// dirty boolean
			count += 4;

			// removed boolean
			count += 4;

			// loading boolean
			count += 4;

			// slot for the parent pointer
			count += 4;

			// child map
			// TODO this isn't quite right but is ok for now
			count += 4;
			String[] childrenNames = node.childrenNames();
			for (int i = 0; i < childrenNames.length; i++)
				count += sizeof(childrenNames[i]);

			// node change listener list
			// TODO
			count += 4;

			// preference change listener list
			// TODO
			count += 4;

			// cached path
			count += 4;
			count += sizeof(node.absolutePath());

			// key/value pairs
			// TODO this isn't quite right but is ok for now
			count += 4;
			String[] keys = node.keys();
			for (int i = 0; i < keys.length; i++) {
				count += sizeof(keys[i]);
				String value = node.get(keys[i], null);
				count += sizeof(value);
			}

			return count;
		}

		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 (Iterator it = map.entrySet().iterator(); it.hasNext();) {
				Map.Entry entry = (Map.Entry) it.next();
				count += sizeof(entry.getKey());
				count += sizeof(entry.getValue());
			}
			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 44 + 2 * ((String) object).length();
			if (object instanceof byte[])
				return 16 + ((byte[]) object).length;
			if (object instanceof Integer)
				return 16;
			if (object instanceof Map)
				return basicSizeof((Map) object);
			if (object instanceof IEclipsePreferences)
				return basicSizeof((IEclipsePreferences) object);
			if (object instanceof QualifiedName) {
				QualifiedName name = (QualifiedName) object;
				return 20 + sizeof(name.getQualifier()) + sizeof(name.getLocalName());
			}
			// unknown -- use deep size
			return 0;
		}

		void visitTree() throws BackingStoreException {
			// count the number of nodes in the preferences tree
			reset();
			IPreferenceNodeVisitor visitor = new IPreferenceNodeVisitor() {
				public boolean visit(IEclipsePreferences node) {
					try {
						treeSize += sizeof(node);
						nodeCount++;
						int keys = node.keys().length;
						kvCount += keys;
						if (keys == 0)
							emptyNodes++;
						else
							nonEmptyNodes.add(node.absolutePath() + " (" + keys + ")"); //$NON-NLS-1$//$NON-NLS-2$
					} catch (BackingStoreException e) {
						e.printStackTrace();
					}
					return true;
				}
			};
			rootNode.accept(visitor);
		}

		void updateTextView() {
			final StringBuffer buffer = new StringBuffer();
			buffer.append("Size of Eclipse 2.1 preference objects: " + prettyPrint(calculateOldSize()) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			buffer.append("Total node count: " + prettyPrint(nodeCount) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			buffer.append("Nodes without keys: " + prettyPrint(emptyNodes) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			buffer.append("Key/value pairs: " + prettyPrint(kvCount) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			buffer.append("Total size of tree: " + prettyPrint(treeSize) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			buffer.append("Nodes with key/value pairs:\n"); //$NON-NLS-1$
			for (Iterator i = nonEmptyNodes.iterator(); i.hasNext();)
				buffer.append("\t" + i.next() + "\n"); //$NON-NLS-1$//$NON-NLS-2$

			//post changes to UI thread
			viewer.getControl().getDisplay().asyncExec(new Runnable() {
				public void run() {
					if (!viewer.getControl().isDisposed()) {
						IDocument doc = viewer.getDocument();
						doc.set(buffer.toString());
						viewer.setDocument(doc);
					}
				}
			});
		}

		private String prettyPrint(int i) {
			StringBuffer buf = new StringBuffer();
			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 org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	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() {
			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);

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

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

}
