/*******************************************************************************
 * 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:
 *    Evgeny Mandrikov - initial API and implementation
 *
 *******************************************************************************/
package org.jacoco.core.test.filter;

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import org.jacoco.core.analysis.ICounter;
import org.jacoco.core.test.TargetLoader;
import org.jacoco.core.test.filter.targets.Finally;
import org.jacoco.core.test.validation.Source;
import org.jacoco.core.test.validation.ValidationTestBase;
import org.junit.Test;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.LineNumberNode;
import org.objectweb.asm.tree.MethodNode;

/**
 * Test of filtering of duplicated bytecode that is generated for finally block.
 */
public class FinallyTest extends ValidationTestBase {

	private static boolean isJDK8 = !Pattern.compile("1\\.[567]\\.0_(\\d++)")
			.matcher(System.getProperty("java.version")).matches();

	public FinallyTest() {
		super(Finally.class);
	}

	/**
	 * {@link Finally#example(boolean)}
	 */
	@Test
	public void example() {
		if (isJDKCompiler) {
			assertLine("example.0", ICounter.EMPTY);
		} else {
			assertLine("example.0", ICounter.FULLY_COVERED);
		}
		assertLine("example.1", ICounter.FULLY_COVERED, 0, 2);
		assertLine("example.2", ICounter.FULLY_COVERED);
		assertLine("example.3", ICounter.EMPTY);
		assertLine("example.4", ICounter.EMPTY);
	}

	/**
	 * GOTO instructions at the end of duplicates of finally block might have
	 * line number of a last instruction of finally block and hence lead to
	 * unexpected coverage results, like for example in case of ECJ for
	 * {@link Finally#catchNotExecuted()}, {@link Finally#emptyCatch()}. So we
	 * decided to ignore them, even if they can correspond to a real break
	 * statement.
	 * <p>
	 * See also <a href=
	 * "https://bugs.openjdk.java.net/browse/JDK-8180141">JDK-8180141</a> and
	 * <a href=
	 * "https://bugs.openjdk.java.net/browse/JDK-7008643">JDK-7008643</a>.
	 * <p>
	 * {@link Finally#breakStatement()}
	 */
	@Test
	public void breakStatement() {
		assertLine("breakStatement", ICounter.EMPTY);

		assertLine("breakStatement.1", ICounter.FULLY_COVERED);
		assertLine("breakStatement.2", ICounter.EMPTY);
	}

	/**
	 * {@link Finally#catchNotExecuted()}
	 */
	@Test
	public void catchNotExecuted() {
		assertLine("catchNotExecuted.catch", ICounter.NOT_COVERED);
		assertLine("catchNotExecuted.0", ICounter.EMPTY);
		assertLine("catchNotExecuted.1", ICounter.FULLY_COVERED);
		assertLine("catchNotExecuted.2", ICounter.EMPTY);
	}

	/**
	 * {@link Finally#emptyCatch()}
	 */
	@Test
	public void emptyCatch() {
		assertLine("emptyCatch.0", ICounter.EMPTY);
		assertLine("emptyCatch.1", ICounter.FULLY_COVERED);
		assertLine("emptyCatch.2", ICounter.EMPTY);
	}

	/**
	 * {@link Finally#twoRegions()}
	 */
	@Test
	public void twoRegions() {
		assertLine("twoRegions.0", ICounter.EMPTY);
		if (isJDKCompiler && !isJDK8) {
			// https://bugs.openjdk.java.net/browse/JDK-7008643
			assertLine("twoRegions.1", ICounter.PARTLY_COVERED);
			assertLine("twoRegions.return.1", ICounter.EMPTY);
			assertLine("twoRegions.return.2", ICounter.EMPTY);
		} else {
			assertLine("twoRegions.1", ICounter.FULLY_COVERED);
			assertLine("twoRegions.return.1", ICounter.FULLY_COVERED);
			assertLine("twoRegions.return.2", ICounter.NOT_COVERED);
		}
		assertLine("twoRegions.2", ICounter.EMPTY);

		assertLine("twoRegions.if", ICounter.FULLY_COVERED);
		assertLine("twoRegions.region.1", ICounter.FULLY_COVERED);
		assertLine("twoRegions.region.2", ICounter.NOT_COVERED);
	}

	/**
	 * {@link Finally#nested()}
	 */
	@Test
	public void nested() {
		if (isJDKCompiler) {
			assertLine("nested.0", ICounter.EMPTY);
		} else {
			assertLine("nested.0", ICounter.FULLY_COVERED);
		}
		assertLine("nested.1", ICounter.EMPTY);
		assertLine("nested.2", ICounter.FULLY_COVERED);
		if (isJDKCompiler) {
			assertLine("nested.3", ICounter.EMPTY);
		} else {
			assertLine("nested.3", ICounter.FULLY_COVERED);
		}
		assertLine("nested.4", ICounter.FULLY_COVERED);
	}

	/**
	 * {@link Finally#emptyTry()}
	 */
	@Test
	public void emptyTry() {
		assertLine("emptyTry.0", ICounter.EMPTY);
		if (!isJDKCompiler || isJDK8) {
			assertLine("emptyTry.1", ICounter.FULLY_COVERED);
			assertLine("emptyTry.2", ICounter.EMPTY);
		} else {
			// compiler bug fixed in javac >= 1.8:
			assertLine("emptyTry.1", ICounter.PARTLY_COVERED);
			assertLine("emptyTry.2", ICounter.FULLY_COVERED);
		}
	}

	/**
	 * {@link Finally#alwaysCompletesAbruptly()}
	 */
	@Test
	public void alwaysCompletesAbruptly() {
		if (isJDKCompiler) {
			// uncovered case:
			assertLine("alwaysCompletesAbruptly.0", ICounter.EMPTY);
			assertLine("alwaysCompletesAbruptly.1", ICounter.PARTLY_COVERED);
		} else {
			assertLine("alwaysCompletesAbruptly.0", ICounter.PARTLY_COVERED);
			assertLine("alwaysCompletesAbruptly.1", ICounter.FULLY_COVERED);
		}
		assertLine("alwaysCompletesAbruptly.2", ICounter.EMPTY);
	}

	/**
	 * This test studies placement of GOTO instructions.
	 */
	@Test
	public void gotos() throws IOException {
		final Source source = Source.getSourceFor("src", Finally.class);

		final ClassNode classNode = new ClassNode();
		new ClassReader(TargetLoader.getClassDataAsBytes(Finally.class))
				.accept(classNode, 0);
		final Set<String> tags = new HashSet<String>();
		for (final MethodNode m : classNode.methods) {
			if ("main".equals(m.name)) {
				// skip it
				continue;
			}
			int lineNumber = -1;
			for (AbstractInsnNode i = m.instructions
					.getFirst(); i != null; i = i.getNext()) {
				if (AbstractInsnNode.LINE == i.getType()) {
					lineNumber = ((LineNumberNode) i).line;
				}
				if (Opcodes.GOTO == i.getOpcode()) {
					final String line = source.getLine(lineNumber);
					if (line.indexOf('$') < 0) {
						throw new AssertionError(
								"No tag at line " + lineNumber);
					}
					final String tag = line.substring(
							line.indexOf('$') + "$line-".length(),
							line.lastIndexOf('$'));
					tags.add(tag);
				}
			}
		}

		final Set<String> expected = new HashSet<String>();

		if (isJDKCompiler) {
			expected.add("example.2");
		} else {
			expected.add("example.0");
		}

		expected.add("breakStatement.for");
		if (isJDKCompiler) {
			expected.add("breakStatement.1");
			expected.add("breakStatement.2");
		} else {
			expected.add("breakStatement");
		}

		if (isJDKCompiler) {
			expected.add("emptyCatch.2");
		} else {
			expected.add("emptyCatch");
			expected.add("emptyCatch.1");
		}

		if (isJDKCompiler) {
			expected.add("catchNotExecuted.2");
		} else {
			expected.add("catchNotExecuted");
			expected.add("catchNotExecuted.1");
		}

		if (isJDKCompiler) {
			expected.add("nested.5");
			expected.add("nested.6");
		} else {
			expected.add("nested.0");
			expected.add("nested.3");
		}

		if (isJDKCompiler && !isJDK8) {
			expected.add("emptyTry.2");
		}

		if (!isJDKCompiler) {
			expected.add("alwaysCompletesAbruptly.0");
		}

		assertEquals(expected, tags);
	}

}
