/*******************************************************************************
 * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors
 * 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:
 *    Marc R. Hoffmann - initial API and implementation
 *    
 *******************************************************************************/
package org.jacoco.core.runtime;

import static java.lang.String.format;

import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

/**
 * Utility to create and parse options for the runtime agent. Options are
 * represented as a string in the following format:
 * 
 * <pre>
 *   key1=value1,key2=value2,key3=value3
 * </pre>
 */
public final class AgentOptions {

	/**
	 * Specifies the output file for execution data. Default is
	 * <code>jacoco.exec</code> in the working directory.
	 */
	public static final String DESTFILE = "destfile";

	/**
	 * Default value for the "destfile" agent option.
	 */
	public static final String DEFAULT_DESTFILE = "jacoco.exec";

	/**
	 * Specifies whether execution data should be appended to the output file.
	 * Default is <code>true</code>.
	 */
	public static final String APPEND = "append";

	/**
	 * Wildcard expression for class names that should be included for code
	 * coverage. Default is <code>*</code> (all classes included).
	 * 
	 * @see WildcardMatcher
	 */
	public static final String INCLUDES = "includes";

	/**
	 * Wildcard expression for class names that should be excluded from code
	 * coverage. Default is the empty string (no exclusions).
	 * 
	 * @see WildcardMatcher
	 */
	public static final String EXCLUDES = "excludes";

	/**
	 * Wildcard expression for class loaders names for classes that should be
	 * excluded from code coverage. This means all classes loaded by a class
	 * loader which full qualified name matches this expression will be ignored
	 * for code coverage regardless of all other filtering settings. Default is
	 * <code>sun.reflect.DelegatingClassLoader</code>.
	 * 
	 * @see WildcardMatcher
	 */
	public static final String EXCLCLASSLOADER = "exclclassloader";

	/**
	 * Specifies whether also classes from the bootstrap classloader should be
	 * instrumented. Use this feature with caution, it needs heavy
	 * includes/excludes tuning. Default is <code>false</code>.
	 */
	public static final String INCLBOOTSTRAPCLASSES = "inclbootstrapclasses";

	/**
	 * Specifies whether also classes without a source location should be
	 * instrumented. Normally such classes are generated at runtime e.g. by
	 * mocking frameworks and are therefore excluded by default. Default is
	 * <code>false</code>.
	 */
	public static final String INCLNOLOCATIONCLASSES = "inclnolocationclasses";

	/**
	 * Specifies a session identifier that is written with the execution data.
	 * Without this parameter a random identifier is created by the agent.
	 */
	public static final String SESSIONID = "sessionid";

	/**
	 * Specifies whether the agent will automatically dump coverage data on VM
	 * exit. Default is <code>true</code>.
	 */
	public static final String DUMPONEXIT = "dumponexit";

	/**
	 * Specifies the output mode. Default is {@link OutputMode#file}.
	 * 
	 * @see OutputMode#file
	 * @see OutputMode#tcpserver
	 * @see OutputMode#tcpclient
	 * @see OutputMode#none
	 */
	public static final String OUTPUT = "output";

	private static final Pattern OPTION_SPLIT = Pattern
			.compile(",(?=[a-zA-Z0-9_\\-]+=)");

	/**
	 * Possible values for {@link AgentOptions#OUTPUT}.
	 */
	public static enum OutputMode {

		/**
		 * Value for the {@link AgentOptions#OUTPUT} parameter: At VM
		 * termination execution data is written to the file specified by
		 * {@link AgentOptions#DESTFILE}.
		 */
		file,

		/**
		 * Value for the {@link AgentOptions#OUTPUT} parameter: The agent
		 * listens for incoming connections on a TCP port specified by
		 * {@link AgentOptions#ADDRESS} and {@link AgentOptions#PORT}.
		 */
		tcpserver,

		/**
		 * Value for the {@link AgentOptions#OUTPUT} parameter: At startup the
		 * agent connects to a TCP port specified by the
		 * {@link AgentOptions#ADDRESS} and {@link AgentOptions#PORT} attribute.
		 */
		tcpclient,

		/**
		 * Value for the {@link AgentOptions#OUTPUT} parameter: Do not produce
		 * any output.
		 */
		none

	}

	/**
	 * The IP address or DNS name the tcpserver binds to or the tcpclient
	 * connects to. Default is defined by {@link #DEFAULT_ADDRESS}.
	 */
	public static final String ADDRESS = "address";

	/**
	 * Default value for the "address" agent option.
	 */
	public static final String DEFAULT_ADDRESS = null;

	/**
	 * The port the tcpserver binds to or the tcpclient connects to. In
	 * tcpserver mode the port must be available, which means that if multiple
	 * JaCoCo agents should run on the same machine, different ports have to be
	 * specified. Default is defined by {@link #DEFAULT_PORT}.
	 */
	public static final String PORT = "port";

	/**
	 * Default value for the "port" agent option.
	 */
	public static final int DEFAULT_PORT = 6300;

	/**
	 * Specifies where the agent dumps all class files it encounters. The
	 * location is specified as a relative path to the working directory.
	 * Default is <code>null</code> (no dumps).
	 */
	public static final String CLASSDUMPDIR = "classdumpdir";

	/**
	 * Specifies whether the agent should expose functionality via JMX under the
	 * name "org.jacoco:type=Runtime". Default is <code>false</code>.
	 */
	public static final String JMX = "jmx";

	private static final Collection<String> VALID_OPTIONS = Arrays.asList(
			DESTFILE, APPEND, INCLUDES, EXCLUDES, EXCLCLASSLOADER,
			INCLBOOTSTRAPCLASSES, INCLNOLOCATIONCLASSES, SESSIONID, DUMPONEXIT,
			OUTPUT, ADDRESS, PORT, CLASSDUMPDIR, JMX);

	private final Map<String, String> options;

	/**
	 * New instance with all values set to default.
	 */
	public AgentOptions() {
		this.options = new HashMap<String, String>();
	}

	/**
	 * New instance parsed from the given option string.
	 * 
	 * @param optionstr
	 *            string to parse or <code>null</code>
	 */
	public AgentOptions(final String optionstr) {
		this();
		if (optionstr != null && optionstr.length() > 0) {
			for (final String entry : OPTION_SPLIT.split(optionstr)) {
				final int pos = entry.indexOf('=');
				if (pos == -1) {
					throw new IllegalArgumentException(format(
							"Invalid agent option syntax \"%s\".", optionstr));
				}
				final String key = entry.substring(0, pos);
				if (!VALID_OPTIONS.contains(key)) {
					throw new IllegalArgumentException(format(
							"Unknown agent option \"%s\".", key));
				}

				final String value = entry.substring(pos + 1);
				setOption(key, value);
			}

			validateAll();
		}
	}

	/**
	 * New instance read from the given {@link Properties} object.
	 * 
	 * @param properties
	 *            {@link Properties} object to read configuration options from
	 */
	public AgentOptions(final Properties properties) {
		this();
		for (final String key : VALID_OPTIONS) {
			final String value = properties.getProperty(key);
			if (value != null) {
				setOption(key, value);
			}
		}
	}

	private void validateAll() {
		validatePort(getPort());
		getOutput();
	}

	private void validatePort(final int port) {
		if (port < 0) {
			throw new IllegalArgumentException("port must be positive");
		}
	}

	/**
	 * Returns the output file location.
	 * 
	 * @return output file location
	 */
	public String getDestfile() {
		return getOption(DESTFILE, DEFAULT_DESTFILE);
	}

	/**
	 * Sets the output file location.
	 * 
	 * @param destfile
	 *            output file location
	 */
	public void setDestfile(final String destfile) {
		setOption(DESTFILE, destfile);
	}

	/**
	 * Returns whether the output should be appended to an existing file.
	 * 
	 * @return <code>true</code>, when the output should be appended
	 */
	public boolean getAppend() {
		return getOption(APPEND, true);
	}

	/**
	 * Sets whether the output should be appended to an existing file.
	 * 
	 * @param append
	 *            <code>true</code>, when the output should be appended
	 */
	public void setAppend(final boolean append) {
		setOption(APPEND, append);
	}

	/**
	 * Returns the wildcard expression for classes to include.
	 * 
	 * @return wildcard expression for classes to include
	 * @see WildcardMatcher
	 */
	public String getIncludes() {
		return getOption(INCLUDES, "*");
	}

	/**
	 * Sets the wildcard expression for classes to include.
	 * 
	 * @param includes
	 *            wildcard expression for classes to include
	 * @see WildcardMatcher
	 */
	public void setIncludes(final String includes) {
		setOption(INCLUDES, includes);
	}

	/**
	 * Returns the wildcard expression for classes to exclude.
	 * 
	 * @return wildcard expression for classes to exclude
	 * @see WildcardMatcher
	 */
	public String getExcludes() {
		return getOption(EXCLUDES, "");
	}

	/**
	 * Sets the wildcard expression for classes to exclude.
	 * 
	 * @param excludes
	 *            wildcard expression for classes to exclude
	 * @see WildcardMatcher
	 */
	public void setExcludes(final String excludes) {
		setOption(EXCLUDES, excludes);
	}

	/**
	 * Returns the wildcard expression for excluded class loaders.
	 * 
	 * @return expression for excluded class loaders
	 * @see WildcardMatcher
	 */
	public String getExclClassloader() {
		return getOption(EXCLCLASSLOADER, "sun.reflect.DelegatingClassLoader");
	}

	/**
	 * Sets the wildcard expression for excluded class loaders.
	 * 
	 * @param expression
	 *            expression for excluded class loaders
	 * @see WildcardMatcher
	 */
	public void setExclClassloader(final String expression) {
		setOption(EXCLCLASSLOADER, expression);
	}

	/**
	 * Returns whether classes from the bootstrap classloader should be
	 * instrumented.
	 * 
	 * @return <code>true</code> if classes from the bootstrap classloader
	 *         should be instrumented
	 */
	public boolean getInclBootstrapClasses() {
		return getOption(INCLBOOTSTRAPCLASSES, false);
	}

	/**
	 * Sets whether classes from the bootstrap classloader should be
	 * instrumented.
	 * 
	 * @param include
	 *            <code>true</code> if bootstrap classes should be instrumented
	 */
	public void setInclBootstrapClasses(final boolean include) {
		setOption(INCLBOOTSTRAPCLASSES, include);
	}

	/**
	 * Returns whether classes without source location should be instrumented.
	 * 
	 * @return <code>true</code> if classes without source location should be
	 *         instrumented
	 */
	public boolean getInclNoLocationClasses() {
		return getOption(INCLNOLOCATIONCLASSES, false);
	}

	/**
	 * Sets whether classes without source location should be instrumented.
	 * 
	 * @param include
	 *            <code>true</code> if classes without source location should be
	 *            instrumented
	 */
	public void setInclNoLocationClasses(final boolean include) {
		setOption(INCLNOLOCATIONCLASSES, include);
	}

	/**
	 * Returns the session identifier.
	 * 
	 * @return session identifier
	 */
	public String getSessionId() {
		return getOption(SESSIONID, null);
	}

	/**
	 * Sets the session identifier.
	 * 
	 * @param id
	 *            session identifier
	 */
	public void setSessionId(final String id) {
		setOption(SESSIONID, id);
	}

	/**
	 * Returns whether coverage data should be dumped on exit.
	 * 
	 * @return <code>true</code> if coverage data will be written on VM exit
	 */
	public boolean getDumpOnExit() {
		return getOption(DUMPONEXIT, true);
	}

	/**
	 * Sets whether coverage data should be dumped on exit.
	 * 
	 * @param dumpOnExit
	 *            <code>true</code> if coverage data should be written on VM
	 *            exit
	 */
	public void setDumpOnExit(final boolean dumpOnExit) {
		setOption(DUMPONEXIT, dumpOnExit);
	}

	/**
	 * Returns the port on which to listen to when the output is
	 * <code>tcpserver</code> or the port to connect to when output is
	 * <code>tcpclient</code>.
	 * 
	 * @return port to listen on or connect to
	 */
	public int getPort() {
		return getOption(PORT, DEFAULT_PORT);
	}

	/**
	 * Sets the port on which to listen to when output is <code>tcpserver</code>
	 * or the port to connect to when output is <code>tcpclient</code>
	 * 
	 * @param port
	 *            port to listen on or connect to
	 */
	public void setPort(final int port) {
		validatePort(port);
		setOption(PORT, port);
	}

	/**
	 * Gets the hostname or IP address to listen to when output is
	 * <code>tcpserver</code> or connect to when output is
	 * <code>tcpclient</code>
	 * 
	 * @return Hostname or IP address
	 */
	public String getAddress() {
		return getOption(ADDRESS, DEFAULT_ADDRESS);
	}

	/**
	 * Sets the hostname or IP address to listen to when output is
	 * <code>tcpserver</code> or connect to when output is
	 * <code>tcpclient</code>
	 * 
	 * @param address
	 *            Hostname or IP address
	 */
	public void setAddress(final String address) {
		setOption(ADDRESS, address);
	}

	/**
	 * Returns the output mode
	 * 
	 * @return current output mode
	 */
	public OutputMode getOutput() {
		final String value = options.get(OUTPUT);
// BEGIN android-change
//		return value == null ? OutputMode.file : OutputMode.valueOf(value);
		return value == null ? OutputMode.none : OutputMode.valueOf(value);
// END android-change
	}

	/**
	 * Sets the output mode
	 * 
	 * @param output
	 *            Output mode
	 */
	public void setOutput(final String output) {
		setOutput(OutputMode.valueOf(output));
	}

	/**
	 * Sets the output mode
	 * 
	 * @param output
	 *            Output mode
	 */
	public void setOutput(final OutputMode output) {
		setOption(OUTPUT, output.name());
	}

	/**
	 * Returns the location of the directory where class files should be dumped
	 * to.
	 * 
	 * @return dump location or <code>null</code> (no dumps)
	 */
	public String getClassDumpDir() {
		return getOption(CLASSDUMPDIR, null);
	}

	/**
	 * Sets the directory where class files should be dumped to.
	 * 
	 * @param location
	 *            dump location or <code>null</code> (no dumps)
	 */
	public void setClassDumpDir(final String location) {
		setOption(CLASSDUMPDIR, location);
	}

	/**
	 * Returns whether the agent exposes functionality via JMX.
	 * 
	 * @return <code>true</code>, when JMX is enabled
	 */
	public boolean getJmx() {
		return getOption(JMX, false);
	}

	/**
	 * Sets whether the agent should expose functionality via JMX.
	 * 
	 * @param jmx
	 *            <code>true</code> if JMX should be enabled
	 */
	public void setJmx(final boolean jmx) {
		setOption(JMX, jmx);
	}

	private void setOption(final String key, final int value) {
		setOption(key, Integer.toString(value));
	}

	private void setOption(final String key, final boolean value) {
		setOption(key, Boolean.toString(value));
	}

	private void setOption(final String key, final String value) {
		options.put(key, value);
	}

	private String getOption(final String key, final String defaultValue) {
		final String value = options.get(key);
		return value == null ? defaultValue : value;
	}

	private boolean getOption(final String key, final boolean defaultValue) {
		final String value = options.get(key);
		return value == null ? defaultValue : Boolean.parseBoolean(value);
	}

	private int getOption(final String key, final int defaultValue) {
		final String value = options.get(key);
		return value == null ? defaultValue : Integer.parseInt(value);
	}

	/**
	 * Generate required JVM argument based on current configuration and
	 * supplied agent jar location.
	 * 
	 * @param agentJarFile
	 *            location of the JaCoCo Agent Jar
	 * @return Argument to pass to create new VM with coverage enabled
	 */
	public String getVMArgument(final File agentJarFile) {
		return format("-javaagent:%s=%s", agentJarFile, this);
	}

	/**
	 * Generate required quoted JVM argument based on current configuration and
	 * supplied agent jar location.
	 * 
	 * @param agentJarFile
	 *            location of the JaCoCo Agent Jar
	 * @return Quoted argument to pass to create new VM with coverage enabled
	 */
	public String getQuotedVMArgument(final File agentJarFile) {
		return CommandLineSupport.quote(getVMArgument(agentJarFile));
	}

	/**
	 * Generate required quotes JVM argument based on current configuration and
	 * prepends it to the given argument command line. If a agent with the same
	 * JAR file is already specified this parameter is removed from the existing
	 * command line.
	 * 
	 * @param arguments
	 *            existing command line arguments or <code>null</code>
	 * @param agentJarFile
	 *            location of the JaCoCo Agent Jar
	 * @return VM command line arguments prepended with configured JaCoCo agent
	 */
	public String prependVMArguments(final String arguments,
			final File agentJarFile) {
		final List<String> args = CommandLineSupport.split(arguments);
		final String plainAgent = format("-javaagent:%s", agentJarFile);
		for (final Iterator<String> i = args.iterator(); i.hasNext();) {
			if (i.next().startsWith(plainAgent)) {
				i.remove();
			}
		}
		args.add(0, getVMArgument(agentJarFile));
		return CommandLineSupport.quote(args);
	}

	/**
	 * Creates a string representation that can be passed to the agent via the
	 * command line. Might be the empty string, if no options are set.
	 */
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		for (final String key : VALID_OPTIONS) {
			final String value = options.get(key);
			if (value != null) {
				if (sb.length() > 0) {
					sb.append(',');
				}
				sb.append(key).append('=').append(value);
			}
		}
		return sb.toString();
	}

}
