/*******************************************************************************
 * Copyright (c) 2000, 2006 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 Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.runtime.internal.stats;

import java.io.*;
import java.net.URL;
import java.util.*;
import org.eclipse.osgi.baseadaptor.HookConfigurator;
import org.eclipse.osgi.baseadaptor.HookRegistry;
import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingStatsHook;
import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry;
import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
import org.eclipse.osgi.framework.adaptor.BundleWatcher;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Bundle;

public class StatsManager implements BundleWatcher, HookConfigurator, ClassLoadingStatsHook {
	// This connect bundles and their info, and so allows to access the info without running through
	// the bundle registry. This map only contains activated bundles. The key is the bundle Id
	private Hashtable bundles = new Hashtable(20);
	private Map activationStacks = new HashMap(5);
	private static boolean booting = true; // the state of the platform. This value is changed by the InternalPlatform itself.

	private static StatsManager defaultInstance;

	public static boolean MONITOR_ACTIVATION = false;
	public static boolean MONITOR_CLASSES = false;
	public static boolean MONITOR_RESOURCES = false;
	public static String TRACE_FILENAME = "runtime.traces"; //$NON-NLS-1$
	public static String TRACE_FILTERS = "trace.properties"; //$NON-NLS-1$
	public static boolean TRACE_CLASSES = false;
	public static boolean TRACE_BUNDLES = false;
	public static final String FRAMEWORK_SYMBOLICNAME = "org.eclipse.osgi"; //$NON-NLS-1$

	//Option names for spies
	private static final String OPTION_MONITOR_ACTIVATION = FRAMEWORK_SYMBOLICNAME + "/monitor/activation"; //$NON-NLS-1$
	private static final String OPTION_MONITOR_CLASSES = FRAMEWORK_SYMBOLICNAME + "/monitor/classes"; //$NON-NLS-1$
	private static final String OPTION_MONITOR_RESOURCES = FRAMEWORK_SYMBOLICNAME + "/monitor/resources"; //$NON-NLS-1$
	private static final String OPTION_TRACE_BUNDLES = FRAMEWORK_SYMBOLICNAME + "/trace/activation"; //$NON-NLS-1$
	private static final String OPTION_TRACE_CLASSES = FRAMEWORK_SYMBOLICNAME + "/trace/classLoading"; //$NON-NLS-1$
	private static final String OPTION_TRACE_FILENAME = FRAMEWORK_SYMBOLICNAME + "/trace/filename"; //$NON-NLS-1$
	private static final String OPTION_TRACE_FILTERS = FRAMEWORK_SYMBOLICNAME + "/trace/filters"; //$NON-NLS-1$

	static {
		setDebugOptions();
	}

	public static StatsManager getDefault() {
		if (defaultInstance == null) {
			defaultInstance = new StatsManager();
			defaultInstance.initialize();
		}
		return defaultInstance;
	}

	public static void setDebugOptions() {
		FrameworkDebugOptions options = FrameworkDebugOptions.getDefault();
		// may be null if debugging is not enabled
		if (options == null)
			return;
		MONITOR_ACTIVATION = options.getBooleanOption(OPTION_MONITOR_ACTIVATION, false);
		MONITOR_CLASSES = options.getBooleanOption(OPTION_MONITOR_CLASSES, false);
		MONITOR_RESOURCES = options.getBooleanOption(OPTION_MONITOR_RESOURCES, false);
		TRACE_CLASSES = options.getBooleanOption(OPTION_TRACE_CLASSES, false);
		TRACE_BUNDLES = options.getBooleanOption(OPTION_TRACE_BUNDLES, false);
		TRACE_FILENAME = options.getOption(OPTION_TRACE_FILENAME, TRACE_FILENAME);
		TRACE_FILTERS = options.getOption(OPTION_TRACE_FILTERS, TRACE_FILTERS);
	}

	public static void doneBooting() {
		booting = false;
	}

	public static boolean isBooting() {
		return booting;
	}

	/**
	 * Returns the result of converting a list of comma-separated tokens into an array
	 * 
	 * @return the array of string tokens
	 * @param prop the initial comma-separated string
	 */
	public static String[] getArrayFromList(String prop) {
		return ManifestElement.getArrayFromList(prop, ","); //$NON-NLS-1$
	}

	private void initialize() {
		// add the system bundle
		BundleStats bundle = findBundle(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, 0);
		bundle.setTimestamp(System.currentTimeMillis());
		bundle.setActivationOrder(bundles.size());
		bundle.setDuringStartup(booting);
	}

	public void watchBundle(Bundle bundle, int type) {
		switch (type) {
			case BundleWatcher.START_ACTIVATION :
				startActivation(bundle);
				break;
			case BundleWatcher.END_ACTIVATION :
				endActivation(bundle);
				break;
		}
	}

	public void startActivation(Bundle bundle) {
		// should be called from a synchronized location to protect against concurrent updates
		BundleStats info = findBundle(bundle.getSymbolicName(), bundle.getBundleId());
		info.setTimestamp(System.currentTimeMillis());
		info.setActivationOrder(bundles.size());
		info.setDuringStartup(booting);

		Stack activationStack = (Stack) activationStacks.get(Thread.currentThread());
		if (activationStack==null) {
			activationStack = new Stack();
			activationStacks.put(Thread.currentThread(), activationStack);
		}
			
		// set the parentage of activation
		if (activationStack.size() != 0) {
			BundleStats activatedBy = (BundleStats) activationStack.peek();
			activatedBy.activated(info);
			info.setActivatedBy(activatedBy);
		}
		activationStack.push(info);

		if (TRACE_BUNDLES == true) {
			traceActivate(bundle, info);
		}
	}

	public void endActivation(Bundle symbolicName) {
		Stack activationStack = (Stack) activationStacks.get(Thread.currentThread());
		// should be called from a synchronized location to protect against concurrent updates
		BundleStats info = (BundleStats) activationStack.pop();
		info.endActivation();
	}

	private void traceActivate(Bundle bundle, BundleStats info) {
		try {
			PrintWriter output = new PrintWriter(new FileOutputStream(ClassloaderStats.traceFile.getAbsolutePath(), true));
			try {
				long startPosition = ClassloaderStats.traceFile.length();
				output.println("Activating bundle: " + bundle.getSymbolicName()); //$NON-NLS-1$
				output.println("Bundle activation stack:"); //$NON-NLS-1$
				Stack activationStack = (Stack) activationStacks.get(Thread.currentThread());
				for (int i = activationStack.size() - 1; i >= 0; i--)
					output.println("\t" + ((BundleStats) activationStack.get(i)).getSymbolicName()); //$NON-NLS-1$
				output.println("Class loading stack:"); //$NON-NLS-1$
				Stack classStack = ClassloaderStats.getClassStack();
				for (int i = classStack.size() - 1; i >= 0; i--)
					output.println("\t" + ((ClassStats) classStack.get(i)).getClassName()); //$NON-NLS-1$
				output.println("Stack trace:"); //$NON-NLS-1$
				new Throwable().printStackTrace(output);
				info.setTraceStart(startPosition);
			} finally {
				output.close();
				info.setTraceEnd(ClassloaderStats.traceFile.length());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public BundleStats findBundle(String symbolicName, long id) {
		BundleStats result = (BundleStats) bundles.get(new Long(id));
		try {
			if (result == null) {
				result = new BundleStats(symbolicName, id);
				bundles.put(new Long(id), result);
			}
		} catch (IllegalAccessError e) {
			e.printStackTrace();
		}
		return result;
	}

	public BundleStats[] getBundles() {
		return (BundleStats[]) bundles.values().toArray(new BundleStats[bundles.size()]);
	}

	public BundleStats getBundle(long id) {
		return (BundleStats) bundles.get(new Long(id));
	}

	public void preFindLocalClass(String name, ClasspathManager manager) throws ClassNotFoundException {
		if (StatsManager.MONITOR_CLASSES) //Support for performance analysis
			ClassloaderStats.startLoadingClass(getClassloaderId(manager), name);
	}

	public void postFindLocalClass(String name, Class clazz, ClasspathManager manager) {
		if (StatsManager.MONITOR_CLASSES)
			ClassloaderStats.endLoadingClass(getClassloaderId(manager), name, clazz != null);	
	}

	public void preFindLocalResource(String name, ClasspathManager manager) {
		// do nothing
	}

	public void postFindLocalResource(String name, URL resource, ClasspathManager manager) {
		if (StatsManager.MONITOR_RESOURCES)
			if (resource != null && name.endsWith(".properties")) //$NON-NLS-1$
				ClassloaderStats.loadedBundle(getClassloaderId(manager), new ResourceBundleStats(getClassloaderId(manager), name, resource));
		return;
	}

	public void recordClassDefine(String name, Class clazz, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
		// do nothing
	}

	private String getClassloaderId(ClasspathManager loader) {
		return loader.getBaseData().getSymbolicName();
	}

	public void addHooks(HookRegistry hookRegistry) {
		if (Debug.MONITOR_ACTIVATION)
			hookRegistry.addWatcher(StatsManager.getDefault());
		if (StatsManager.MONITOR_CLASSES || StatsManager.MONITOR_RESOURCES)
			hookRegistry.addClassLoadingStatsHook(StatsManager.getDefault());
	}
}
