/*******************************************************************************
 * Copyright (c) 2003, 2016 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 Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.osgi.internal.debug;

import java.io.*;
import java.net.URL;
import java.util.*;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.location.LocationHelper;
import org.eclipse.osgi.service.debug.*;
import org.osgi.framework.*;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

/**
 * The DebugOptions implementation class that allows accessing the list of debug options specified
 * for the application as well as creating {@link DebugTrace} objects for the purpose of having
 * dynamic enablement of debug tracing.
 * 
 * @since 3.1
 */
public class FrameworkDebugOptions implements DebugOptions, ServiceTrackerCustomizer<DebugOptionsListener, DebugOptionsListener> {

	private static final String OSGI_DEBUG = "osgi.debug"; //$NON-NLS-1$
	private static final String OSGI_DEBUG_VERBOSE = "osgi.debug.verbose"; //$NON-NLS-1$
	public static final String PROP_TRACEFILE = "osgi.tracefile"; //$NON-NLS-1$
	/** The default name of the .options file if loading when the -debug command-line argument is used */
	private static final String OPTIONS = ".options"; //$NON-NLS-1$

	/** A lock object used to synchronize access to the trace file */
	private final static Object writeLock = new Object();
	/** monitor used to lock the options maps */
	private final Object lock = new Object();
	/** A current map of all the options with values set */
	private Properties options = null;
	/** A map of all the disabled options with values set at the time debug was disabled */
	private Properties disabledOptions = null;
	/** A cache of all of the bundles <code>DebugTrace</code> in the format <key,value> --> <bundle name, DebugTrace> */
	protected final Map<String, DebugTrace> debugTraceCache = new HashMap<>();
	/** The File object to store messages.  This value may be null. */
	protected File outFile = null;
	/** Is verbose debugging enabled?  Changing this value causes a new tracing session to start. */
	protected boolean verboseDebug = true;
	/** A flag to determine if the message being written is done to a new file (i.e. should the header information be written) */
	private boolean newSession = true;
	private final EquinoxConfiguration environmentInfo;
	private volatile BundleContext context;
	private volatile ServiceTracker<DebugOptionsListener, DebugOptionsListener> listenerTracker;

	public FrameworkDebugOptions(EquinoxConfiguration environmentInfo) {
		this.environmentInfo = environmentInfo;
		// check if verbose debugging was set during initialization.  This needs to be set even if debugging is disabled
		this.verboseDebug = Boolean.valueOf(environmentInfo.getConfiguration(OSGI_DEBUG_VERBOSE, Boolean.TRUE.toString())).booleanValue();
		// if no debug option was specified, don't even bother to try.
		// Must ensure that the options slot is null as this is the signal to the
		// platform that debugging is not enabled.
		String debugOptionsFilename = environmentInfo.getConfiguration(OSGI_DEBUG);
		if (debugOptionsFilename == null)
			return;
		options = new Properties();
		URL optionsFile;
		if (debugOptionsFilename.length() == 0) {
			// default options location is user.dir (install location may be r/o so
			// is not a good candidate for a trace options that need to be updatable by
			// by the user)
			String userDir = System.getProperty("user.dir").replace(File.separatorChar, '/'); //$NON-NLS-1$
			if (!userDir.endsWith("/")) //$NON-NLS-1$
				userDir += "/"; //$NON-NLS-1$
			debugOptionsFilename = new File(userDir, OPTIONS).toString();
		}
		optionsFile = LocationHelper.buildURL(debugOptionsFilename, false);
		if (optionsFile == null) {
			System.out.println("Unable to construct URL for options file: " + debugOptionsFilename); //$NON-NLS-1$
			return;
		}
		System.out.print("Debug options:\n    " + optionsFile.toExternalForm()); //$NON-NLS-1$
		try {
			InputStream input = LocationHelper.getStream(optionsFile);
			try {
				options.load(input);
				System.out.println(" loaded"); //$NON-NLS-1$
			} finally {
				input.close();
			}
		} catch (FileNotFoundException e) {
			System.out.println(" not found"); //$NON-NLS-1$
		} catch (IOException e) {
			System.out.println(" did not parse"); //$NON-NLS-1$
			e.printStackTrace(System.out);
		}
		// trim off all the blanks since properties files don't do that.
		for (Object key : options.keySet()) {
			options.put(key, ((String) options.get(key)).trim());
		}
	}

	public void start(BundleContext bc) {
		this.context = bc;
		listenerTracker = new ServiceTracker<>(bc, DebugOptionsListener.class.getName(), this);
		listenerTracker.open();
	}

	public void stop(BundleContext bc) {
		listenerTracker.close();
		listenerTracker = null;
		this.context = null;
	}

	/**
	 * @see DebugOptions#getBooleanOption(String, boolean)
	 */
	public boolean getBooleanOption(String option, boolean defaultValue) {
		String optionValue = getOption(option);
		return optionValue != null ? optionValue.equalsIgnoreCase("true") : defaultValue; //$NON-NLS-1$
	}

	/**
	 * @see DebugOptions#getOption(String)
	 */
	public String getOption(String option) {
		return getOption(option, null);
	}

	/**
	 * @see DebugOptions#getOption(String, String)
	 */
	public String getOption(String option, String defaultValue) {
		synchronized (lock) {
			if (options != null) {
				return options.getProperty(option, defaultValue);
			}
		}
		return defaultValue;
	}

	/**
	 * @see DebugOptions#getIntegerOption(String, int)
	 */
	public int getIntegerOption(String option, int defaultValue) {
		String value = getOption(option);
		try {
			return value == null ? defaultValue : Integer.parseInt(value);
		} catch (NumberFormatException e) {
			return defaultValue;
		}
	}

	@SuppressWarnings({"unchecked", "rawtypes"})
	public Map<String, String> getOptions() {
		Map<String, String> snapShot = new HashMap<>();
		synchronized (lock) {
			if (options != null)
				snapShot.putAll((Map) options);
			else if (disabledOptions != null)
				snapShot.putAll((Map) disabledOptions);
		}
		return snapShot;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#getAllOptions()
	 */
	String[] getAllOptions() {

		String[] optionsArray = null;
		synchronized (lock) {
			if (options != null) {
				optionsArray = new String[options.size()];
				final Iterator<Map.Entry<Object, Object>> entrySetIterator = options.entrySet().iterator();
				int i = 0;
				while (entrySetIterator.hasNext()) {
					Map.Entry<Object, Object> entry = entrySetIterator.next();
					optionsArray[i] = ((String) entry.getKey()) + "=" + ((String) entry.getValue()); //$NON-NLS-1$
					i++;
				}
			}
		}
		if (optionsArray == null) {
			optionsArray = new String[1]; // TODO this is strange; null is the only element so we can print null in writeSession
		}
		return optionsArray;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#removeOption(java.lang.String)
	 */
	public void removeOption(String option) {
		if (option == null)
			return;
		String fireChangedEvent = null;
		synchronized (lock) {
			if (options != null && options.remove(option) != null) {
				fireChangedEvent = getSymbolicName(option);
			}
		}
		// Send the options change event outside the sync block
		if (fireChangedEvent != null) {
			optionsChanged(fireChangedEvent);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#setOption(java.lang.String, java.lang.String)
	 */
	public void setOption(String option, String value) {

		if (option == null || value == null) {
			throw new IllegalArgumentException("The option and value must not be null."); //$NON-NLS-1$
		}
		String fireChangedEvent = null;
		value = value != null ? value.trim() : null;
		synchronized (lock) {
			if (options != null) {
				// get the current value
				String currentValue = options.getProperty(option);

				if (currentValue != null) {
					if (!currentValue.equals(value)) {
						fireChangedEvent = getSymbolicName(option);
					}
				} else {
					if (value != null) {
						fireChangedEvent = getSymbolicName(option);
					}
				}
				if (fireChangedEvent != null) {
					options.put(option, value);
				}
			}
		}
		// Send the options change event outside the sync block
		if (fireChangedEvent != null) {
			optionsChanged(fireChangedEvent);
		}
	}

	private String getSymbolicName(String option) {
		int firstSlashIndex = option.indexOf("/"); //$NON-NLS-1$
		if (firstSlashIndex > 0)
			return option.substring(0, firstSlashIndex);
		return null;
	}

	@SuppressWarnings("cast")
	public void setOptions(Map<String, String> ops) {
		if (ops == null)
			throw new IllegalArgumentException("The options must not be null."); //$NON-NLS-1$
		Properties newOptions = new Properties();
		for (Iterator<Map.Entry<String, String>> entries = ops.entrySet().iterator(); entries.hasNext();) {
			Map.Entry<String, String> entry = entries.next();
			if (!(entry.getKey() instanceof String) || !(entry.getValue() instanceof String))
				throw new IllegalArgumentException("Option keys and values must be of type String: " + entry.getKey() + "=" + entry.getValue()); //$NON-NLS-1$ //$NON-NLS-2$
			newOptions.put(entry.getKey(), entry.getValue().trim());
		}
		Set<String> fireChangesTo = null;

		synchronized (lock) {
			if (options == null) {
				disabledOptions = newOptions;
				// no events to fire
				return;
			}
			fireChangesTo = new HashSet<>();
			// first check for removals
			for (Iterator<Object> keys = options.keySet().iterator(); keys.hasNext();) {
				String key = (String) keys.next();
				if (!newOptions.containsKey(key)) {
					String symbolicName = getSymbolicName(key);
					if (symbolicName != null)
						fireChangesTo.add(symbolicName);
				}
			}
			// now check for changes to existing values
			for (Iterator<Map.Entry<Object, Object>> newEntries = newOptions.entrySet().iterator(); newEntries.hasNext();) {
				Map.Entry<Object, Object> entry = newEntries.next();
				String existingValue = (String) options.get(entry.getKey());
				if (!entry.getValue().equals(existingValue)) {
					String symbolicName = getSymbolicName((String) entry.getKey());
					if (symbolicName != null)
						fireChangesTo.add(symbolicName);
				}
			}
			// finally set the actual options
			options = newOptions;
		}
		if (fireChangesTo != null)
			for (Iterator<String> iChanges = fireChangesTo.iterator(); iChanges.hasNext();)
				optionsChanged(iChanges.next());
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#isDebugEnabled()
	 */
	public boolean isDebugEnabled() {
		synchronized (lock) {
			return options != null;
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#setDebugEnabled()
	 */
	public void setDebugEnabled(boolean enabled) {
		boolean fireChangedEvent = false;
		synchronized (lock) {
			if (enabled) {
				if (options != null)
					return;
				// notify the trace that a new session is started
				this.newSession = true;

				// enable platform debugging - there is no .options file
				environmentInfo.setConfiguration(OSGI_DEBUG, ""); //$NON-NLS-1$
				if (disabledOptions != null) {
					options = disabledOptions;
					disabledOptions = null;
					// fire changed event to indicate some options were re-enabled
					fireChangedEvent = true;
				} else {
					options = new Properties();
				}
			} else {
				if (options == null)
					return;
				// disable platform debugging.
				environmentInfo.clearConfiguration(OSGI_DEBUG);
				if (options.size() > 0) {
					// Save the current options off in case debug is re-enabled
					disabledOptions = options;
					// fire changed event to indicate some options were disabled
					fireChangedEvent = true;
				}
				options = null;
			}
		}
		if (fireChangedEvent) {
			// (Bug 300911) need to fire event to listeners that options have been disabled
			optionsChanged("*"); //$NON-NLS-1$
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#createTrace(java.lang.String)
	 */
	public final DebugTrace newDebugTrace(String bundleSymbolicName) {

		return this.newDebugTrace(bundleSymbolicName, null);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#createTrace(java.lang.String, java.lang.Class)
	 */
	public final DebugTrace newDebugTrace(String bundleSymbolicName, Class<?> traceEntryClass) {

		DebugTrace debugTrace = null;
		synchronized (debugTraceCache) {
			debugTrace = debugTraceCache.get(bundleSymbolicName);
			if (debugTrace == null) {
				debugTrace = new EclipseDebugTrace(bundleSymbolicName, this, traceEntryClass);
				debugTraceCache.put(bundleSymbolicName, debugTrace);
			}
		}
		return debugTrace;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#getFile()
	 */
	public final File getFile() {

		return this.outFile;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#setFile(java.io.File)
	 */
	public void setFile(final File traceFile) {
		synchronized (lock) {
			this.outFile = traceFile;
			if (this.outFile != null)
				environmentInfo.setConfiguration(PROP_TRACEFILE, this.outFile.getAbsolutePath());
			else
				environmentInfo.clearConfiguration(PROP_TRACEFILE);
			// the file changed so start a new session
			this.newSession = true;
		}
	}

	boolean newSession() {
		synchronized (lock) {
			if (newSession) {
				this.newSession = false;
				return true;
			}
			return false;
		}
	}

	Object getWriteLock() {
		return writeLock;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#getVerbose()
	 */
	boolean isVerbose() {

		return this.verboseDebug;
	}

	EquinoxConfiguration getConfiguration() {
		return this.environmentInfo;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.osgi.service.debug.DebugOptions#setVerbose(boolean)
	 */
	public void setVerbose(final boolean verbose) {
		synchronized (lock) {
			this.verboseDebug = verbose;
			// the verbose flag changed so start a new session
			this.newSession = true;
		}
	}

	/**
	 * Notifies the trace listener for the specified bundle that its option-path has changed.
	 * @param bundleSymbolicName The bundle of the owning trace listener to notify.
	 */
	private void optionsChanged(String bundleSymbolicName) {
		// use osgi services to get the listeners
		BundleContext bc = context;
		if (bc == null)
			return;
		// do not use the service tracker because that is only used to call all listeners initially when they are registered
		// here we only want the services with the specified name.
		ServiceReference<?>[] listenerRefs = null;
		try {
			listenerRefs = bc.getServiceReferences(DebugOptionsListener.class.getName(), "(" + DebugOptions.LISTENER_SYMBOLICNAME + "=" + bundleSymbolicName + ")"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
		} catch (InvalidSyntaxException e) {
			// consider logging; should not happen
		}
		if (listenerRefs == null)
			return;
		for (int i = 0; i < listenerRefs.length; i++) {
			DebugOptionsListener service = (DebugOptionsListener) bc.getService(listenerRefs[i]);
			if (service == null)
				continue;
			try {
				service.optionsChanged(this);
			} catch (Throwable t) {
				// TODO consider logging
			} finally {
				bc.ungetService(listenerRefs[i]);
			}
		}
	}

	public DebugOptionsListener addingService(ServiceReference<DebugOptionsListener> reference) {
		DebugOptionsListener listener = context.getService(reference);
		listener.optionsChanged(this);
		return listener;
	}

	public void modifiedService(ServiceReference<DebugOptionsListener> reference, DebugOptionsListener service) {
		// nothing
	}

	public void removedService(ServiceReference<DebugOptionsListener> reference, DebugOptionsListener service) {
		context.ungetService(reference);
	}
}
