/*******************************************************************************
 * Copyright (c) 2009, 2018 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 org.jacoco.core.data.ExecutionData;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.data.IExecutionDataVisitor;
import org.jacoco.core.data.ISessionInfoVisitor;
import org.jacoco.core.data.SessionInfo;
import org.jacoco.core.internal.instr.InstrSupport;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

/**
 * Container for runtime execution and meta data. All access to the runtime data
 * is thread safe.
 */
public class RuntimeData {

	/** store for execution data */
	protected final ExecutionDataStore store;

	private long startTimeStamp;

	private String sessionId;

	/**
	 * Creates a new runtime.
	 */
	public RuntimeData() {
		// BEGIN android-change
		this(new ExecutionDataStore());
		// END android-change
	}

	// BEGIN android-change
	/**
	 * Creates a new runtime, reusing an existing {@link ExecutionDataStore}.
	 * 
	 * @param store
	 *            the store to reuse
	 */
	public RuntimeData(ExecutionDataStore store) {
		this.store = store;
		sessionId = "<none>";
		startTimeStamp = System.currentTimeMillis();
	}
	// END android-change

	/**
	 * Sets a session identifier for this runtime. The identifier is used when
	 * execution data is collected. If no identifier is explicitly set a
	 * identifier is generated from the host name and a random number. This
	 * method can be called at any time.
	 * 
	 * @see #collect(IExecutionDataVisitor, ISessionInfoVisitor, boolean)
	 * @param id
	 *            new session identifier
	 */
	public void setSessionId(final String id) {
		sessionId = id;
	}

	/**
	 * Get the current a session identifier for this runtime.
	 * 
	 * @see #setSessionId(String)
	 * @return current session identifier
	 */
	public String getSessionId() {
		return sessionId;
	}

	/**
	 * Collects the current execution data and writes it to the given
	 * {@link IExecutionDataVisitor} object.
	 * 
	 * @param executionDataVisitor
	 *            handler to write coverage data to
	 * @param sessionInfoVisitor
	 *            handler to write session information to
	 * @param reset
	 *            if <code>true</code> the current coverage information is also
	 *            cleared
	 */
	public final void collect(final IExecutionDataVisitor executionDataVisitor,
			final ISessionInfoVisitor sessionInfoVisitor, final boolean reset) {
		synchronized (store) {
			final SessionInfo info = new SessionInfo(sessionId, startTimeStamp,
					System.currentTimeMillis());
			sessionInfoVisitor.visitSessionInfo(info);
			store.accept(executionDataVisitor);
			if (reset) {
				reset();
			}
		}
	}

	/**
	 * Resets all coverage information.
	 */
	public final void reset() {
		synchronized (store) {
			store.reset();
			startTimeStamp = System.currentTimeMillis();
		}
	}

	/**
	 * Returns the coverage data for the class with the given identifier. If
	 * there is no data available under the given id a new entry is created.
	 * This is a synchronized access to the underlying store.
	 * 
	 * @param id
	 *            class identifier
	 * @param name
	 *            VM name of the class
	 * @param probecount
	 *            probe data length
	 * @return execution data
	 */
	public ExecutionData getExecutionData(final Long id, final String name,
			final int probecount) {
		synchronized (store) {
			return store.get(id, name, probecount);
		}
	}

	/**
	 * Retrieves the execution probe array for a given class. The passed
	 * {@link Object} array instance is used for parameters and the return value
	 * as follows. Call parameters:
	 * 
	 * <ul>
	 * <li>args[0]: class id ({@link Long})
	 * <li>args[1]: vm class name ({@link String})
	 * <li>args[2]: probe count ({@link Integer})
	 * </ul>
	 * 
	 * Return value:
	 * 
	 * <ul>
	 * <li>args[0]: probe array (<code>boolean[]</code>)
	 * </ul>
	 * 
	 * @param args
	 *            parameter array of length 3
	 */
	public void getProbes(final Object[] args) {
		final Long classid = (Long) args[0];
		final String name = (String) args[1];
		final int probecount = ((Integer) args[2]).intValue();
		args[0] = getExecutionData(classid, name, probecount).getProbes();
	}

	/**
	 * In violation of the regular semantic of {@link Object#equals(Object)}
	 * this implementation is used as the interface to the execution data store.
	 * 
	 * @param args
	 *            the arguments as an {@link Object} array
	 * @return has no meaning
	 */
	@Override
	public boolean equals(final Object args) {
		if (args instanceof Object[]) {
			getProbes((Object[]) args);
		}
		return super.equals(args);
	}

	/**
	 * Generates code that creates the argument array for the
	 * {@link #getProbes(Object[])} method. The array instance is left on the
	 * operand stack. The generated code requires a stack size of 5.
	 * 
	 * @param classid
	 *            class identifier
	 * @param classname
	 *            VM class name
	 * @param probecount
	 *            probe count for this class
	 * @param mv
	 *            visitor to emit generated code
	 */
	public static void generateArgumentArray(final long classid,
			final String classname, final int probecount, final MethodVisitor mv) {
		mv.visitInsn(Opcodes.ICONST_3);
		mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");

		// Class Id:
		mv.visitInsn(Opcodes.DUP);
		mv.visitInsn(Opcodes.ICONST_0);
		mv.visitLdcInsn(Long.valueOf(classid));
		mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
				"(J)Ljava/lang/Long;", false);
		mv.visitInsn(Opcodes.AASTORE);

		// Class Name:
		mv.visitInsn(Opcodes.DUP);
		mv.visitInsn(Opcodes.ICONST_1);
		mv.visitLdcInsn(classname);
		mv.visitInsn(Opcodes.AASTORE);

		// Probe Count:
		mv.visitInsn(Opcodes.DUP);
		mv.visitInsn(Opcodes.ICONST_2);
		InstrSupport.push(mv, probecount);
		mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer",
				"valueOf", "(I)Ljava/lang/Integer;", false);
		mv.visitInsn(Opcodes.AASTORE);
	}

	/**
	 * Generates the code that calls a {@link RuntimeData} instance through the
	 * JRE API method {@link Object#equals(Object)}. The code pops a
	 * {@link Object} instance from the stack and pushes the probe array of type
	 * <code>boolean[]</code> on the operand stack. The generated code requires
	 * a stack size of 6.
	 * 
	 * @param classid
	 *            class identifier
	 * @param classname
	 *            VM class name
	 * @param probecount
	 *            probe count for this class
	 * @param mv
	 *            visitor to emit generated code
	 */
	public static void generateAccessCall(final long classid,
			final String classname, final int probecount, final MethodVisitor mv) {
		// stack[0]: Ljava/lang/Object;

		generateArgumentArray(classid, classname, probecount, mv);

		// stack[1]: [Ljava/lang/Object;
		// stack[0]: Ljava/lang/Object;

		mv.visitInsn(Opcodes.DUP_X1);

		// stack[2]: [Ljava/lang/Object;
		// stack[1]: Ljava/lang/Object;
		// stack[0]: [Ljava/lang/Object;

		mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals",
				"(Ljava/lang/Object;)Z", false);
		mv.visitInsn(Opcodes.POP);

		// stack[0]: [Ljava/lang/Object;

		mv.visitInsn(Opcodes.ICONST_0);
		mv.visitInsn(Opcodes.AALOAD);

		// stack[0]: [Z

		mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC);
	}

}
