/*******************************************************************************
 * Copyright (c) 2009, 2019 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.internal.instr;

import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

/**
 * Internal utility to add probes into the control flow of a method. The code
 * for a probe simply sets a certain slot of a boolean array to true. In
 * addition the probe array has to be retrieved at the beginning of the method
 * and stored in a local variable.
 */
class ProbeInserter extends MethodVisitor implements IProbeInserter {

	private final IProbeArrayStrategy arrayStrategy;

	/**
	 * <code>true</code> if method is a class or interface initialization
	 * method.
	 */
	private final boolean clinit;

	/** Position of the inserted variable. */
	private final int variable;

	/** Maximum stack usage of the code to access the probe array. */
	private int accessorStackSize;

	/**
	 * Creates a new {@link ProbeInserter}.
	 * 
	 * @param access
	 *            access flags of the adapted method
	 * @param name
	 *            the method's name
	 * @param desc
	 *            the method's descriptor
	 * @param mv
	 *            the method visitor to which this adapter delegates calls
	 * @param arrayStrategy
	 *            callback to create the code that retrieves the reference to
	 *            the probe array
	 */
	ProbeInserter(final int access, final String name, final String desc, final MethodVisitor mv,
			final IProbeArrayStrategy arrayStrategy) {
		super(InstrSupport.ASM_API_VERSION, mv);
		this.clinit = InstrSupport.CLINIT_NAME.equals(name);
		this.arrayStrategy = arrayStrategy;
		int pos = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
		for (final Type t : Type.getArgumentTypes(desc)) {
			pos += t.getSize();
		}
		variable = pos;
	}

	public void insertProbe(final int id) {

		// BEGIN android-change
		// For a probe we call setProbe on the IExecutionData object.

		mv.visitVarInsn(Opcodes.ALOAD, variable);

		// Stack[0]: Lorg/jacoco/core/data/IExecutionData;

		InstrSupport.push(mv, id);

		// Stack[1]: I
		// Stack[0]: Lorg/jacoco/core/data/IExecutionData;

		mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "org/jacoco/core/data/IExecutionData", "setProbe", "(I)V", true);
		// END android-change
	}

	@Override
	public void visitCode() {
		accessorStackSize = arrayStrategy.storeInstance(mv, clinit, variable);
		mv.visitCode();
	}

	@Override
	public final void visitVarInsn(final int opcode, final int var) {
		mv.visitVarInsn(opcode, map(var));
	}

	@Override
	public final void visitIincInsn(final int var, final int increment) {
		mv.visitIincInsn(map(var), increment);
	}

	@Override
	public final void visitLocalVariable(final String name, final String desc,
			final String signature, final Label start, final Label end,
			final int index) {
		mv.visitLocalVariable(name, desc, signature, start, end, map(index));
	}

	@Override
	public void visitMaxs(final int maxStack, final int maxLocals) {
		// Max stack size of the probe code is 3 which can add to the
		// original stack size depending on the probe locations. The accessor
		// stack size is an absolute maximum, as the accessor code is inserted
		// at the very beginning of each method when the stack size is empty.
		final int increasedStack = Math.max(maxStack + 3, accessorStackSize);
		mv.visitMaxs(increasedStack, maxLocals + 1);
	}

	private int map(final int var) {
		if (var < variable) {
			return var;
		} else {
			return var + 1;
		}
	}

	@Override
	public final void visitFrame(final int type, final int nLocal,
			final Object[] local, final int nStack, final Object[] stack) {

		if (type != Opcodes.F_NEW) { // uncompressed frame
			throw new IllegalArgumentException(
					"ClassReader.accept() should be called with EXPAND_FRAMES flag");
		}

		final Object[] newLocal = new Object[Math.max(nLocal, variable) + 1];
		int idx = 0; // Arrays index for existing locals
		int newIdx = 0; // Array index for new locals
		int pos = 0; // Current variable position
		while (idx < nLocal || pos <= variable) {
			if (pos == variable) {
				newLocal[newIdx++] = InstrSupport.DATAFIELD_DESC;
				pos++;
			} else {
				if (idx < nLocal) {
					final Object t = local[idx++];
					newLocal[newIdx++] = t;
					pos++;
					if (t == Opcodes.LONG || t == Opcodes.DOUBLE) {
						pos++;
					}
				} else {
					// Fill unused slots with TOP
					newLocal[newIdx++] = Opcodes.TOP;
					pos++;
				}
			}
		}
		mv.visitFrame(type, newIdx, newLocal, nStack, stack);
	}

}
