#!/usr/bin/env bash
#
# Copyright 2015 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -eu

# Load the test setup defined in the parent directory
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CURRENT_DIR}/../integration_test_setup.sh" \
  || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
source "${CURRENT_DIR}/coverage_helpers.sh" \
  || { echo "coverage_helpers.sh not found!" >&2; exit 1; }


RULES_JAVA_REPO_NAME=$(cat "$(rlocation io_bazel/src/test/shell/bazel/RULES_JAVA_REPO_NAME)")
JAVA_TOOLS_ZIP="$1"; shift
JAVA_TOOLS_PREBUILT_ZIP="$1"; shift

override_java_tools "${RULES_JAVA_REPO_NAME}" "${JAVA_TOOLS_ZIP}" "${JAVA_TOOLS_PREBUILT_ZIP}"

COVERAGE_GENERATOR_WORKSPACE_FILE="$1"; shift
if [[ "${COVERAGE_GENERATOR_WORKSPACE_FILE}" != "released" ]]; then
  COVERAGE_GENERATOR_DIR="$(dirname "$(rlocation $COVERAGE_GENERATOR_WORKSPACE_FILE)")"
  add_to_bazelrc "build --override_repository=bazel_tools+remote_coverage_tools_extension+remote_coverage_tools=${COVERAGE_GENERATOR_DIR}"
fi

if [[ $# -gt 0 ]]; then
    JAVA_RUNTIME_VERSION="$1"; shift
    add_to_bazelrc "build --java_runtime_version=${JAVA_RUNTIME_VERSION}"
    add_to_bazelrc "build --tool_java_runtime_version=${JAVA_RUNTIME_VERSION}"
fi

function set_up() {
  add_rules_java "MODULE.bazel"
}

function test_java_test_coverage() {
  cat <<EOF > BUILD
load("@rules_java//toolchains:default_java_toolchain.bzl", "default_java_toolchain")
load("@rules_java//java:java_test.bzl", "java_test")
load("@rules_java//java:java_library.bzl", "java_library")

java_test(
    name = "test",
    srcs = glob(["src/test/**/*.java"]),
    test_class = "com.example.TestCollatz",
    deps = [":collatz-lib"],
)

java_library(
    name = "collatz-lib",
    srcs = glob(["src/main/**/*.java"]),
)

default_java_toolchain(
    name = "custom_toolchain"
)
EOF

  mkdir -p src/main/com/example
  cat <<EOF > src/main/com/example/Collatz.java
package com.example;

public class Collatz {

  public static int getCollatzFinal(int n) {
    if (n == 1) {
      return 1;
    }
    if (n % 2 == 0) {
      return getCollatzFinal(n / 2);
    } else {
      return getCollatzFinal(n * 3 + 1);
    }
  }

}
EOF

  mkdir -p src/test/com/example
  cat <<EOF > src/test/com/example/TestCollatz.java
package com.example;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class TestCollatz {

  @Test
  public void testGetCollatzFinal() {
    assertEquals(Collatz.getCollatzFinal(1), 1);
    assertEquals(Collatz.getCollatzFinal(5), 1);
    assertEquals(Collatz.getCollatzFinal(10), 1);
    assertEquals(Collatz.getCollatzFinal(21), 1);
  }

}
EOF

  bazel coverage --test_output=all //:test &>$TEST_log || fail "Coverage for //:test failed"

  # Regression test for https://github.com/bazelbuild/bazel/issues/28637
  # Verifies that the coverage runtime classpath uses correct runfiles paths,
  # i.e., workspace-local jars are found by singlejar without errors.
  assert_not_contains "Cannot open input jar" "$TEST_log"

  local coverage_file_path="$( get_coverage_file_path_from_test_log )"

  local expected_result="SF:src/main/com/example/Collatz.java
FN:3,com/example/Collatz::<init> ()V
FN:6,com/example/Collatz::getCollatzFinal (I)I
FNDA:0,com/example/Collatz::<init> ()V
FNDA:1,com/example/Collatz::getCollatzFinal (I)I
FNF:2
FNH:1
BRDA:6,0,0,1
BRDA:6,0,1,1
BRDA:9,0,0,1
BRDA:9,0,1,1
BRF:4
BRH:4
DA:3,0
DA:6,1
DA:7,1
DA:9,1
DA:10,1
DA:12,1
LH:5
LF:6
end_of_record"

  assert_coverage_result "$expected_result" "$coverage_file_path"

  bazel coverage --test_output=all --java_toolchain=//:custom_toolchain //:test &>$TEST_log || fail "Coverage with default_java_toolchain for //:test failed"
  assert_coverage_result "$expected_result" "$coverage_file_path"
}

function test_java_test_coverage_combined_report() {

  cat <<EOF > BUILD
load("@rules_java//java:java_library.bzl", "java_library")
load("@rules_java//java:java_test.bzl", "java_test")

java_test(
    name = "test",
    srcs = glob(["src/test/**/*.java"]),
    test_class = "com.example.TestCollatz",
    deps = [":collatz-lib"],
)

java_library(
    name = "collatz-lib",
    srcs = glob(["src/main/**/*.java"]),
)
EOF

  mkdir -p src/main/com/example
  cat <<EOF > src/main/com/example/Collatz.java
package com.example;

public class Collatz {

  public static int getCollatzFinal(int n) {
    if (n == 1) {
      return 1;
    }
    if (n % 2 == 0) {
      return getCollatzFinal(n / 2);
    } else {
      return getCollatzFinal(n * 3 + 1);
    }
  }

}
EOF

  mkdir -p src/test/com/example
  cat <<EOF > src/test/com/example/TestCollatz.java
package com.example;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class TestCollatz {

  @Test
  public void testGetCollatzFinal() {
    assertEquals(Collatz.getCollatzFinal(1), 1);
    assertEquals(Collatz.getCollatzFinal(5), 1);
    assertEquals(Collatz.getCollatzFinal(10), 1);
    assertEquals(Collatz.getCollatzFinal(21), 1);
  }

}
EOF

  # Ensure that coverage succeeds even with lazily built runfiles trees for the
  # merger tool.
  bazel coverage \
      --nobuild_runfile_links \
      --test_output=all //:test --coverage_report_generator=@bazel_tools//tools/test:coverage_report_generator --combined_report=lcov &>$TEST_log \
   || echo "Coverage for //:test failed"

  local expected_result="SF:src/main/com/example/Collatz.java
FN:3,com/example/Collatz::<init> ()V
FN:6,com/example/Collatz::getCollatzFinal (I)I
FNDA:0,com/example/Collatz::<init> ()V
FNDA:1,com/example/Collatz::getCollatzFinal (I)I
FNF:2
FNH:1
BRDA:6,0,0,1
BRDA:6,0,1,1
BRDA:9,0,0,1
BRDA:9,0,1,1
BRF:4
BRH:4
DA:3,0
DA:6,1
DA:7,1
DA:9,1
DA:10,1
DA:12,1
LH:5
LF:6
end_of_record"

  assert_coverage_result "$expected_result" "./bazel-out/_coverage/_coverage_report.dat"
}

function test_java_test_java_import_coverage() {

  cat <<EOF > BUILD
load("@rules_java//java:java_test.bzl", "java_test")
load("@rules_java//java:java_import.bzl", "java_import")
load("@rules_java//java:java_library.bzl", "java_library")

java_test(
    name = "test",
    srcs = glob(["src/test/**/*.java"]),
    test_class = "com.example.TestCollatz",
    deps = [":collatz-import"],
)

java_import(
    name = "collatz-import",
    jars = [":libcollatz-lib.jar"],
)

java_library(
    name = "collatz-lib",
    srcs = glob(["src/main/**/*.java"]),
)
EOF

  mkdir -p src/main/com/example
  cat <<EOF > src/main/com/example/Collatz.java
package com.example;

public class Collatz {

  public static int getCollatzFinal(int n) {
    if (n == 1) {
      return 1;
    }
    if (n % 2 == 0) {
      return getCollatzFinal(n / 2);
    } else {
      return getCollatzFinal(n * 3 + 1);
    }
  }

}
EOF

  mkdir -p src/test/com/example
  cat <<EOF > src/test/com/example/TestCollatz.java
package com.example;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class TestCollatz {

  @Test
  public void testGetCollatzFinal() {
    assertEquals(Collatz.getCollatzFinal(1), 1);
    assertEquals(Collatz.getCollatzFinal(5), 1);
    assertEquals(Collatz.getCollatzFinal(10), 1);
    assertEquals(Collatz.getCollatzFinal(21), 1);
  }

}
EOF

  bazel coverage --test_output=all //:test &>$TEST_log || fail "Coverage for //:test failed"
  local coverage_file_path="$( get_coverage_file_path_from_test_log )"

  local expected_result="SF:src/main/com/example/Collatz.java
FN:3,com/example/Collatz::<init> ()V
FN:6,com/example/Collatz::getCollatzFinal (I)I
FNDA:0,com/example/Collatz::<init> ()V
FNDA:1,com/example/Collatz::getCollatzFinal (I)I
FNF:2
FNH:1
BRDA:6,0,0,1
BRDA:6,0,1,1
BRDA:9,0,0,1
BRDA:9,0,1,1
BRF:4
BRH:4
DA:3,0
DA:6,1
DA:7,1
DA:9,1
DA:10,1
DA:12,1
LH:5
LF:6
end_of_record"

  assert_coverage_result "$expected_result" "$coverage_file_path"
}

function test_run_jar_in_subprocess_empty_env() {
  mkdir -p java/cov
  mkdir -p javatests/cov
  cat >java/cov/BUILD <<EOF
load("@rules_java//java:java_binary.bzl", "java_binary")

package(default_visibility=['//visibility:public'])
java_binary(name = 'Cov',
            main_class = 'cov.Cov',
            srcs = ['Cov.java'])
EOF

  cat >java/cov/Cov.java <<EOF
package cov;
public class Cov {
  public static void main(String[] args) {
    if (args.length == 1) {
      if (Boolean.parseBoolean(args[0])) {
        System.out.println("Boolean.parseBoolean returned true");  // line 6
      } else {
        System.out.println("Boolean.parseBoolean returned false"); // line 8
      }
    }
  }
}
EOF

  cat >javatests/cov/BUILD <<EOF
load("@rules_java//java:java_test.bzl", "java_test")
java_test(name = 'CovTest',
          srcs = ['CovTest.java'],
          data = ['//java/cov:Cov_deploy.jar'],
          test_class = 'cov.CovTest')
EOF

  cat >javatests/cov/CovTest.java <<EOF
package cov;
import junit.framework.TestCase;
import java.io.*;
import java.nio.channels.*;
import java.net.InetAddress;
public class CovTest extends TestCase {
  private static Process startSubprocess(String arg) throws Exception {
   String path = System.getenv("TEST_SRCDIR") + "/_main/java/cov/Cov_deploy.jar";
    String[] command = {
      // Run the deploy jar by invoking JVM because the integration tests
      // cannot use the java launcher (b/29388516).
      System.getProperty("java.home") + "/bin/java", "-jar", path, arg
    };
    ProcessBuilder pb = new ProcessBuilder(command);
    pb.environment().clear();
    return pb.start();
  }
  public void testTrivial() throws Exception {
    Process subprocessTrue = startSubprocess("true");
    Process subprocessFalse = startSubprocess("false");
    subprocessTrue.waitFor();
    subprocessFalse.waitFor();
    String line;
    BufferedReader input = new BufferedReader(new InputStreamReader(subprocessTrue.getInputStream()));
    while ((line = input.readLine()) != null) {
      System.out.println(line);
     }
    input.close();
    BufferedReader err = new BufferedReader(new InputStreamReader(subprocessTrue.getErrorStream()));
    while ((line = err.readLine()) != null) {
      System.out.println(line);
     }
    err.close();

    input = new BufferedReader(new InputStreamReader(subprocessFalse.getInputStream()));
    while ((line = input.readLine()) != null) {
      System.out.println(line);
     }
    input.close();
    err = new BufferedReader(new InputStreamReader(subprocessFalse.getErrorStream()));
    while ((line = err.readLine()) != null) {
      System.out.println(line);
     }
    err.close();
  }
}
EOF

  # Only assess that the coverage run was successful.
  # --nooutputredirect is needed for blaze to print the output of the jar
  bazel coverage --test_output=all --test_arg=--nooutputredirect \
    javatests/cov:CovTest >"${TEST_log}" || fail "Expected success"
  expect_not_log "JACOCO_METADATA_JAR/JACOCO_MAIN_CLASS environment variables not set"
  expect_log "Boolean.parseBoolean returned true"
  expect_log "Boolean.parseBoolean returned false"
}

function test_runtime_deploy_jar() {
  mkdir -p java/cov
  mkdir -p javatests/cov
  cat >java/cov/BUILD <<EOF
load("@rules_java//java:java_binary.bzl", "java_binary")
load("@rules_java//java:java_library.bzl", "java_library")

package(default_visibility=['//visibility:public'])
java_binary(
    name = 'RandomBinary',
    main_class = 'cov.RandomBinary',
    srcs = ['RandomBinary.java'],
)

java_library(
    name = 'Cov',
    srcs = ['Cov.java']
)
EOF

  cat >java/cov/RandomBinary.java <<EOF
package cov;
public class RandomBinary {
  public static void main(String[] args) throws Exception {
    throw new Exception("RandomBinary should not be run!");
  }
}
EOF

  cat >java/cov/Cov.java <<EOF
package cov;
public class Cov {
  public static void main(String[] args) {
    if (args.length == 1) {
      if (Boolean.parseBoolean(args[0])) {
        System.out.println("Boolean.parseBoolean returned true");  // line 6
      } else {
        System.out.println("Boolean.parseBoolean returned false"); // line 8
      }
    }
  }
}
EOF

  cat >javatests/cov/BUILD <<EOF
load("@rules_java//java:java_test.bzl", "java_test")

java_test(name = 'CovTest',
          srcs = ['CovTest.java'],
          deps = ['//java/cov:Cov'],
          runtime_deps = ['//java/cov:RandomBinary_deploy.jar'],
          test_class = 'cov.CovTest')
EOF

  cat >javatests/cov/CovTest.java <<EOF
package cov;
import junit.framework.TestCase;
import java.io.*;
import java.nio.channels.*;
import java.net.InetAddress;
public class CovTest extends TestCase {
  public void testTrivial() throws Exception {
    Cov.main(new String[] {"true"});
    Cov.main(new String[] {"false"});
  }
}
EOF

  bazel coverage --test_output=all --instrumentation_filter=//java/cov \
      javatests/cov:CovTest >"${TEST_log}"
  local coverage_file_path="$( get_coverage_file_path_from_test_log )"
  assert_coverage_result "java/cov/Cov.java" ${coverage_file_path}
}

function test_runtime_and_data_deploy_jars() {
  if [[ "${JAVA_TOOLS_ZIP}" == released ]]; then
      # TODO: Enable test after the next java_tools release.
      return 0
  fi
  mkdir -p java/cov
  mkdir -p javatests/cov
  cat >java/cov/BUILD <<EOF
load("@rules_java//java:java_binary.bzl", "java_binary")

package(default_visibility=['//visibility:public'])
java_binary(
    name = 'RandomBinary',
    main_class = 'cov.RandomBinary',
    srcs = ['RandomBinary.java'],
)

java_binary(
    name = 'Cov',
    srcs = ['Cov.java'],
    main_class = 'cov.Cov'
)
EOF

  cat >java/cov/RandomBinary.java <<EOF
package cov;
public class RandomBinary {
  public static void main(String[] args) throws Exception {
    throw new Exception("RandomBinary should not be run!");
  }
}
EOF

  cat >java/cov/Cov.java <<EOF
package cov;
public class Cov {
  public static void main(String[] args) {
    if (args.length == 1) {
      if (Boolean.parseBoolean(args[0])) {
        System.out.println("Boolean.parseBoolean returned true");  // line 6
      } else {
        System.out.println("Boolean.parseBoolean returned false"); // line 8
      }
    }
  }
}
EOF

  cat >javatests/cov/BUILD <<EOF
load("@rules_java//java:java_test.bzl", "java_test")

java_test(name = 'CovTest',
          srcs = ['CovTest.java'],
          data = ['//java/cov:Cov_deploy.jar'],
          runtime_deps = ['//java/cov:RandomBinary_deploy.jar'],
          test_class = 'cov.CovTest')
EOF

  cat >javatests/cov/CovTest.java <<EOF
package cov;
import junit.framework.TestCase;
import java.io.*;
import java.nio.channels.*;
import java.net.InetAddress;
public class CovTest extends TestCase {
  private static Process startSubprocess(String arg) throws Exception {
   String path = System.getenv("TEST_SRCDIR") + "/_main/java/cov/Cov_deploy.jar";
    String[] command = {
      // Run the deploy jar by invoking JVM because the integration tests
      // cannot use the java launcher (b/29388516).
      System.getProperty("java.home") + "/bin/java", "-jar", path, arg
    };
    return new ProcessBuilder(command).start();
  }
  public void testTrivial() throws Exception {
    Process subprocessTrue = startSubprocess("true");
    Process subprocessFalse = startSubprocess("false");
    subprocessTrue.waitFor();
    subprocessFalse.waitFor();
    String line;
    BufferedReader input = new BufferedReader(new InputStreamReader(subprocessTrue.getInputStream()));
    while ((line = input.readLine()) != null) {
      System.out.println(line);
     }
    input.close();
    BufferedReader err = new BufferedReader(new InputStreamReader(subprocessTrue.getErrorStream()));
    while ((line = err.readLine()) != null) {
      System.out.println(line);
     }
    err.close();

    input = new BufferedReader(new InputStreamReader(subprocessFalse.getInputStream()));
    while ((line = input.readLine()) != null) {
      System.out.println(line);
     }
    input.close();
    err = new BufferedReader(new InputStreamReader(subprocessFalse.getErrorStream()));
    while ((line = err.readLine()) != null) {
      System.out.println(line);
     }
    err.close();
  }
}
EOF

  # --nooutputredirect is needed for blaze to print the output of the deploy jar
  bazel coverage --test_output=all --test_arg=--nooutputredirect \
      --instrumentation_filter=//java/cov javatests/cov:CovTest >"${TEST_log}"
  local coverage_file_path="$( get_coverage_file_path_from_test_log )"

  local expected_result_cov="SF:java/cov/Cov.java
FN:2,cov/Cov::<init> ()V
FN:4,cov/Cov::main ([Ljava/lang/String;)V
FNDA:0,cov/Cov::<init> ()V
FNDA:2,cov/Cov::main ([Ljava/lang/String;)V
FNF:2
FNH:1
BRDA:4,0,0,2
BRDA:4,0,1,0
BRDA:5,0,0,1
BRDA:5,0,1,1
BRF:4
BRH:3
DA:2,0
DA:4,2
DA:5,2
DA:6,1
DA:8,1
DA:11,2
LH:5
LF:6
end_of_record"

  local expected_result_random="SF:java/cov/RandomBinary.java
FN:2,cov/RandomBinary::<init> ()V
FN:4,cov/RandomBinary::main ([Ljava/lang/String;)V
FNDA:0,cov/RandomBinary::<init> ()V
FNDA:0,cov/RandomBinary::main ([Ljava/lang/String;)V
FNF:2
FNH:0
DA:2,0
DA:4,0
LH:0
LF:2
end_of_record"

  # we do not assert the order of the source files in the coverage report
  # only that they are both included and correctly merged
  assert_coverage_result "$expected_result_cov" ${coverage_file_path}
  assert_coverage_result "$expected_result_random" ${coverage_file_path}
}

function test_java_coverage_with_classpath_jar() {
  # Verifies the logic in JacocoCoverageRunner can unpack the classpath jar
  # created when the classpath is too long.
  cat <<EOF > BUILD
load("@rules_java//java:java_library.bzl", "java_library")
load("@rules_java//java:java_test.bzl", "java_test")

java_library(
    name = "lib",
    srcs = ["src/main/java/lib/Lib.java"],
)

java_test(
    name = "lib_test",
    srcs = ["src/test/java/lib/TestLib.java"],
    test_class = "lib.TestLib",
    deps = [":lib"],
)
EOF

  mkdir -p src/main/java/lib
  cat <<EOF > src/main/java/lib/Lib.java
package lib;
public class Lib {
  public static int calcX(int y) {
    return y * 2;
  }
}
EOF

  mkdir -p src/test/java/lib
  cat <<EOF > src/test/java/lib/TestLib.java
package lib;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class TestLib {
  @Test
  public void testCalcX() throws Exception {
    assertEquals(6, Lib.calcX(3));
  }
}
EOF

  bazel coverage \
    --test_output=all \
    --combined_report=lcov \
    --instrumentation_filter="lib" \
    --action_env CLASSPATH_LIMIT=1 \
    //:lib_test &>$TEST_log \
      || echo "Coverage for //:test failed"

  local coverage_file_path="$(get_coverage_file_path_from_test_log)"
  local expected_result="SF:src/main/java/lib/Lib.java
FN:2,lib/Lib::<init> ()V
FN:4,lib/Lib::calcX (I)I
FNDA:0,lib/Lib::<init> ()V
FNDA:1,lib/Lib::calcX (I)I
FNF:2
FNH:1
DA:2,0
DA:4,1
LH:1
LF:2"

  assert_coverage_result "$expected_result" "$coverage_file_path"
}

function test_java_coverage_with_classpath_and_data_jar() {
  cat <<EOF > BUILD
load("@rules_java//java:java_binary.bzl", "java_binary")
load("@rules_java//java:java_test.bzl", "java_test")
load("@rules_java//java:java_library.bzl", "java_library")

java_binary(
    name = "foo",
    srcs = ["src/main/java/foo/Foo.java"],
    main_class = "foo.Foo",
    deploy_manifest_lines = [
      "Premain-Class: foo.Foo",
    ],
    use_launcher = False,
)

java_library(
    name = "lib",
    srcs = ["src/main/java/lib/Lib.java"],
)

java_test(
    name = "lib_test",
    srcs = ["src/test/java/lib/TestLib.java"],
    test_class = "lib.TestLib",
    deps = [":lib"],
    jvm_flags = ["-javaagent:\$(rootpath :foo_deploy.jar)"],
    data = [":foo_deploy.jar"],
)
EOF

  mkdir -p src/main/java/foo
  cat <<EOF > src/main/java/foo/Foo.java
package foo;
public class Foo {
  public static void main(String[] args) {
    return;
  }

  public static void premain(String args) {
    return;
  }

  public static void agentmain(String args) {
    return;
  }
}
EOF

  mkdir -p src/main/java/lib
  cat <<EOF > src/main/java/lib/Lib.java
package lib;
public class Lib {
  public static int calcX(int y) {
    return y * 2;
  }
}
EOF

  mkdir -p src/test/java/lib
  cat <<EOF > src/test/java/lib/TestLib.java
package lib;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class TestLib {
  @Test
  public void testCalcX() throws Exception {
    assertEquals(6, Lib.calcX(3));
  }
}
EOF

  bazel coverage \
    --test_output=all \
    --combined_report=lcov \
    --instrumentation_filter="lib" \
    --action_env CLASSPATH_LIMIT=1 \
    //:lib_test &>$TEST_log \
      || echo "Coverage for //:test failed"

  local coverage_file_path="$(get_coverage_file_path_from_test_log)"
  local expected_result="SF:src/main/java/lib/Lib.java
FN:2,lib/Lib::<init> ()V
FN:4,lib/Lib::calcX (I)I
FNDA:0,lib/Lib::<init> ()V
FNDA:1,lib/Lib::calcX (I)I
FNF:2
FNH:1
DA:2,0
DA:4,1
LH:1
LF:2"

  assert_coverage_result "$expected_result" "$coverage_file_path"
}

function test_java_string_switch_coverage() {
  if [[ "${JAVA_TOOLS_ZIP}" == released ]]; then
      # TODO: Enable test after the next java_tools release.
      return 0
  fi
  # Verify that Jacoco's filtering is being applied.
  # Switches on strings generate over double the number of expected branches
  # (because a switch on String::hashCode is made first) - these branches should
  # be filtered.
  cat <<EOF > BUILD
load("@rules_java//java:java_test.bzl", "java_test")
load("@rules_java//java:java_library.bzl", "java_library")

java_test(
    name = "test",
    srcs = glob(["src/test/**/*.java"]),
    test_class = "com.example.TestSwitch",
    deps = [":switch-lib"],
)

java_library(
    name = "switch-lib",
    srcs = glob(["src/main/**/*.java"]),
)
EOF

  mkdir -p src/main/com/example
  cat <<EOF > src/main/com/example/Switch.java
package com.example;

public class Switch {

  public static int switchString(String input) {
    switch (input) {
      case "AA":
        return 0;
      case "BB":
        return 1;
      case "CC":
        return 2;
      default:
        return -1;
    }
  }
}
EOF

  mkdir -p src/test/com/example
  cat <<EOF > src/test/com/example/TestSwitch.java
package com.example;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class TestSwitch {

  @Test
  public void testValues() {
    assertEquals(Switch.switchString("CC"), 2);
    // "Aa" has a hash collision with "BB"
    assertEquals(Switch.switchString("Aa"), -1);
    assertEquals(Switch.switchString("DD"), -1);
  }

}
EOF

  bazel coverage --test_output=all //:test --coverage_report_generator=@bazel_tools//tools/test:coverage_report_generator --combined_report=lcov &>$TEST_log \
   || echo "Coverage for //:test failed"

  local coverage_file_path="$( get_coverage_file_path_from_test_log )"

  local expected_result="SF:src/main/com/example/Switch.java
FN:3,com/example/Switch::<init> ()V
FN:6,com/example/Switch::switchString (Ljava/lang/String;)I
FNDA:0,com/example/Switch::<init> ()V
FNDA:1,com/example/Switch::switchString (Ljava/lang/String;)I
FNF:2
FNH:1
BRDA:6,0,0,1
BRDA:6,0,1,0
BRDA:6,0,2,0
BRDA:6,0,3,1
BRF:4
BRH:2
DA:3,0
DA:6,1
DA:8,0
DA:10,0
DA:12,1
DA:14,1
LH:3
LF:6
end_of_record"

  assert_coverage_result "$expected_result" "$coverage_file_path"
}


function test_finally_block_branch_coverage() {
  if [[ "${JAVA_TOOLS_ZIP}" == released ]]; then
      # TODO: Enable test after the next java_tools release.
      return 0
  fi
  # Verify branches in finally blocks are handled correctly.
  # The java compiler duplicates finally blocks for the various code paths that
  # may enter them (e.g. via an exception handler or when no exception is
  # thrown).
  cat <<EOF > BUILD
load("@rules_java//java:java_test.bzl", "java_test")
load("@rules_java//java:java_library.bzl", "java_library")

java_test(
    name = "test",
    srcs = glob(["src/test/**/*.java"]),
    test_class = "com.example.TestFinally",
    deps = [":finally-lib"],
)

java_library(
    name = "finally-lib",
    srcs = glob(["src/main/**/*.java"]),
)
EOF

  mkdir -p src/main/com/example
  cat <<EOF > src/main/com/example/Finally.java
package com.example;

public class Finally {

  private static int secret = 0;

  public static int runFinally(int x) {
    try {
      if (x == 1 || x == -1) {
        throw new RuntimeException();
      }
      if (x % 2 == 0) {
        return x * 2;
      } else {
        return x * 2 - 1;
      }
    } finally {
      if (x >= 0) {
        secret++;
      } else {
        secret--;
      }
    }
  }
}
EOF

  mkdir -p src/test/com/example
  cat <<EOF > src/test/com/example/TestFinally.java
package com.example;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import org.junit.Test;

public class TestFinally {

  @Test
  public void testEven() {
    assertEquals(4, Finally.runFinally(2));
  }
  @Test
  public void testOdd() {
    assertEquals(5, Finally.runFinally(3));
  }
  @Test
  public void testNegativeEven() {
    assertEquals(-4, Finally.runFinally(-2));
  }
  @Test
  public void testNegativeOdd() {
    assertEquals(-7, Finally.runFinally(-3));
  }
  @Test
  public void testException() {
    assertThrows(RuntimeException.class, () -> Finally.runFinally(1));
  }
  @Test
  public void testNegativeException() {
    assertThrows(RuntimeException.class, () -> Finally.runFinally(-1));
  }

}
EOF

  # For the sake of brevity, only check the output for the branches
  # corresponding to the finally block in the method under test rather than the
  # entire coverage output.
  bazel coverage --test_output=all //:test \
    --coverage_report_generator=@bazel_tools//tools/test:coverage_report_generator \
    --combined_report=lcov &>$TEST_log \
    --test_filter=TestFinally.testNegativeException \
   || echo "Coverage for //:test failed"

  # if (x == 1 || x == -1) is a "jump if eq" followed by a "jump if not eq", so
  # the branch ordering is reversed for the second comparison
  local coverage_file_path="$( get_coverage_file_path_from_test_log )"
  local expected_result="BRDA:9,0,0,1
BRDA:9,0,1,0
BRDA:9,0,2,1
BRDA:9,0,3,0
BRDA:12,0,0,-
BRDA:12,0,1,-
BRDA:18,0,0,0
BRDA:18,0,1,1
BRF:8
BRH:3"
  assert_coverage_result "$expected_result" "$coverage_file_path"

  bazel coverage --test_output=all //:test \
    --coverage_report_generator=@bazel_tools//tools/test:coverage_report_generator \
    --combined_report=lcov &>$TEST_log \
    --test_filter=".*(testOdd|testNegativeOdd)" \
   || echo "Coverage for //:test failed"

  local coverage_file_path="$( get_coverage_file_path_from_test_log )"
  local expected_result="BRDA:9,0,0,1
BRDA:9,0,1,0
BRDA:9,0,2,0
BRDA:9,0,3,1
BRDA:12,0,0,0
BRDA:12,0,1,1
BRDA:18,0,0,1
BRDA:18,0,1,1
BRF:8
BRH:5"
  assert_coverage_result "$expected_result" "$coverage_file_path"

  bazel coverage --test_output=all //:test \
    --coverage_report_generator=@bazel_tools//tools/test:coverage_report_generator \
    --combined_report=lcov &>$TEST_log \
    --test_filter=".*(testEven|testNegativeOdd)" \
   || echo "Coverage for //:test failed"

  local coverage_file_path="$( get_coverage_file_path_from_test_log )"
  local expected_result="BRDA:9,0,0,1
BRDA:9,0,1,0
BRDA:9,0,2,0
BRDA:9,0,3,1
BRDA:12,0,0,1
BRDA:12,0,1,1
BRDA:18,0,0,1
BRDA:18,0,1,1
BRF:8
BRH:6"
  assert_coverage_result "$expected_result" "$coverage_file_path"

  bazel coverage --test_output=all //:test \
    --coverage_report_generator=@bazel_tools//tools/test:coverage_report_generator \
    --combined_report=lcov &>$TEST_log \
    --test_filter=".*(testNegativeEven|testException)" \
   || echo "Coverage for //:test failed"

  local coverage_file_path="$( get_coverage_file_path_from_test_log )"
  local expected_result="BRDA:9,0,0,1
BRDA:9,0,1,1
BRDA:9,0,2,0
BRDA:9,0,3,1
BRDA:12,0,0,1
BRDA:12,0,1,0
BRDA:18,0,0,1
BRDA:18,0,1,1
BRF:8
BRH:6"
  assert_coverage_result "$expected_result" "$coverage_file_path"

  bazel coverage --test_output=all //:test \
    --coverage_report_generator=@bazel_tools//tools/test:coverage_report_generator \
    --combined_report=lcov &>$TEST_log \
    --test_filter=".*(testNegativeEven|testNegativeOdd)" \
   || echo "Coverage for //:test failed"

  local coverage_file_path="$( get_coverage_file_path_from_test_log )"
  local expected_result="BRDA:9,0,0,1
BRDA:9,0,1,0
BRDA:9,0,2,0
BRDA:9,0,3,1
BRDA:12,0,0,1
BRDA:12,0,1,1
BRDA:18,0,0,0
BRDA:18,0,1,1
BRF:8
BRH:5"
  assert_coverage_result "$expected_result" "$coverage_file_path"

  bazel coverage --test_output=all //:test \
    --coverage_report_generator=@bazel_tools//tools/test:coverage_report_generator \
    --combined_report=lcov &>$TEST_log \
    --test_filter=".*(testOdd|testException)" \
   || echo "Coverage for //:test failed"

  local coverage_file_path="$( get_coverage_file_path_from_test_log )"
  local expected_result="BRDA:9,0,0,1
BRDA:9,0,1,1
BRDA:9,0,2,0
BRDA:9,0,3,1
BRDA:12,0,0,0
BRDA:12,0,1,1
BRDA:18,0,0,1
BRDA:18,0,1,0
BRF:8
BRH:5"
  assert_coverage_result "$expected_result" "$coverage_file_path"
}

function test_branch_in_switch_coverage() {
  if [[ "${JAVA_TOOLS_ZIP}" == released ]]; then
      # TODO: Enable test after the next java_tools release.
      return 0
  fi
  # Verify our branch analysis handles an edge case where an instruction is
  # reached from several different branch sets.
  # https://github.com/bazelbuild/bazel/commit/a915b00547129bc15c7efcf5794407854ecf450c
  # broke this.

  mkdir -p foo
  cat <<EOF > foo/BUILD
load("@rules_java//java:java_library.bzl", "java_library")
load("@rules_java//java:java_test.bzl", "java_test")

java_test(
  name = "fooTest",
  srcs = ["FooTest.java"],
  test_class = "foo.FooTest",
  deps = [":foo"],
)

java_library(
  name = "foo",
  srcs = ["Foo.java"],
)
EOF

  cat <<EOF > foo/Foo.java
package foo;

public class Foo {
  public static String calcFoo(int x) {
    String out = "default";
    switch(x) {
      case 0:
        out = "zero";
        break;
      case 1:
      case 2:
      case 3:
        break;
      case 4:
        if (out.startsWith("d")) {
          out = "four";
        }
      default:
        break;
    }
    return out;
  }
}
EOF

  cat <<EOF > foo/FooTest.java
package foo;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class FooTest {

  @Test
  public void testMiddleValue() {
    assertEquals("default", Foo.calcFoo(2));
  }

  @Test
  public void testFour() {
    assertEquals("four", Foo.calcFoo(4));
  }
}
EOF

  bazel coverage //foo:fooTest \
    --coverage_report_generator=@bazel_tools//tools/test:coverage_report_generator \
    --test_output=all \
    --combined_report=lcov &>$TEST_log \
    || echo "Coverage for //foo:fooTest failed"

  local coverage_file_path="$(get_coverage_file_path_from_test_log)"
  local expected_line_result="DA:3,0
DA:5,1
DA:6,1
DA:8,0
DA:9,0
DA:13,1
DA:15,1
DA:16,1
DA:21,1"
  local expected_branch_result="BRDA:6,0,0,0
BRDA:6,0,1,0
BRDA:6,0,2,1
BRDA:6,0,3,1
BRDA:15,0,0,1
BRDA:15,0,1,0
BRF:6
BRH:3"
  assert_coverage_result "$expected_line_result" "$coverage_file_path"
  assert_coverage_result "$expected_branch_result" "$coverage_file_path"
}

function test_java_test_coverage_cc_binary() {
  if is_gcov_missing_or_wrong_version; then
    echo "Skipping test." && return
  fi

  ########### Setup source files and BUILD file ###########
  add_rules_cc "MODULE.bazel"
  cat <<EOF > BUILD
load("@rules_java//java:java_test.bzl", "java_test")

java_test(
    name = "NumJava",
    srcs = ["NumJava.java"],
    data = ["//examples/cpp:num-world"],
    main_class = "main.NumJava",
    use_testrunner = False,
)
EOF
  cat <<EOF > NumJava.java
package main;

public class NumJava {
  public static void main(String[] args) throws java.io.IOException {
    Runtime.getRuntime().exec("examples/cpp/num-world");
  }
}
EOF

  mkdir -p examples/cpp

  cat <<EOF > examples/cpp/BUILD
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
load("@rules_cc//cc:cc_library.bzl", "cc_library")

package(default_visibility = ["//visibility:public"])

cc_binary(
    name = "num-world",
    srcs = ["num-world.cc"],
    deps = [":num-lib"],
)

cc_library(
    name = "num-lib",
    srcs = ["num-lib.cc"],
    hdrs = ["num-lib.h"]
)
EOF

  cat <<EOF > examples/cpp/num-world.cc
#include "examples/cpp/num-lib.h"

using num::NumLib;

int main(int argc, char** argv) {
  NumLib lib(30);
  int value = 42;
  if (argc > 1) {
    value = 43;
  }
  lib.add_number(value);
  return 0;
}
EOF

  cat <<EOF > examples/cpp/num-lib.h
#ifndef EXAMPLES_CPP_NUM_LIB_H_
#define EXAMPLES_CPP_NUM_LIB_H_

namespace num {

class NumLib {
 public:
  explicit NumLib(int number);

  int add_number(int value);

 private:
  int number_;
};

}  // namespace num

#endif  // EXAMPLES_CPP_NUM_LIB_H_
EOF

  cat <<EOF > examples/cpp/num-lib.cc
#include "examples/cpp/num-lib.h"

namespace num {

NumLib::NumLib(int number) : number_(number) {
}

int NumLib::add_number(int value) {
  return number_ + value;
}

}  // namespace num
EOF

  ########### Run bazel coverage ###########
  bazel coverage  --test_output=all \
      //:NumJava &>$TEST_log || fail "Coverage for //:NumJava failed"

  ########### Assert coverage results. ###########
  local coverage_file_path="$( get_coverage_file_path_from_test_log )"
  local expected_result_num_lib="SF:examples/cpp/num-lib.cc
FN:8,_ZN3num6NumLib10add_numberEi
FN:5,_ZN3num6NumLibC2Ei
FNDA:1,_ZN3num6NumLib10add_numberEi
FNDA:1,_ZN3num6NumLibC2Ei
FNF:2
FNH:2
DA:5,1
DA:6,1
DA:8,1
DA:9,1
LH:4
LF:4
end_of_record"
  assert_coverage_result "$expected_result_num_lib" "$coverage_file_path"
  local coverage_result_num_lib_header="SF:examples/cpp/num-world.cc
FN:5,main
FNDA:1,main
FNF:1
FNH:1
BRDA:6,0,0,1
BRDA:6,0,1,0
BRDA:8,0,0,0
BRDA:8,0,1,1
BRDA:11,0,0,1
BRDA:11,0,1,0
BRF:6
BRH:3
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,0
DA:11,1
DA:12,1
LH:6
LF:7
end_of_record"
  assert_cc_coverage_result "$coverage_result_num_lib_header" "$coverage_file_path"
}

function setup_external_java_target() {
  cat >> MODULE.bazel <<'EOF'
local_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(
    name = "other_repo",
    path = "other_repo",
)
EOF

  cat > BUILD <<'EOF'
load("@rules_java//java:java_library.bzl", "java_library")

java_library(
    name = "math",
    srcs = ["src/main/com/example/Math.java"],
    visibility = ["//visibility:public"],
)
EOF

  mkdir -p src/main/com/example
  cat > src/main/com/example/Math.java <<'EOF'
package com.example;

public class Math {

  public static boolean isEven(int n) {
    return n % 2 == 0;
  }
}
EOF

  mkdir -p other_repo
  touch other_repo/REPO.bazel

  cat > other_repo/BUILD <<'EOF'
load("@rules_java//java:java_library.bzl", "java_library")
load("@rules_java//java:java_test.bzl", "java_test")

java_library(
    name = "collatz",
    srcs = ["src/main/com/example/Collatz.java"],
    deps = ["@//:math"],
)

java_test(
    name = "test",
    srcs = ["src/test/com/example/TestCollatz.java"],
    test_class = "com.example.TestCollatz",
    deps = [":collatz"],
)
EOF

  mkdir -p other_repo/src/main/com/example
  cat > other_repo/src/main/com/example/Collatz.java <<'EOF'
package com.example;

public class Collatz {

  public static int getCollatzFinal(int n) {
    if (n == 1) {
      return 1;
    }
    if (Math.isEven(n)) {
      return getCollatzFinal(n / 2);
    } else {
      return getCollatzFinal(n * 3 + 1);
    }
  }

}
EOF

  mkdir -p other_repo/src/test/com/example
  cat > other_repo/src/test/com/example/TestCollatz.java <<'EOF'
package com.example;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class TestCollatz {

  @Test
  public void testGetCollatzFinal() {
    assertEquals(Collatz.getCollatzFinal(1), 1);
    assertEquals(Collatz.getCollatzFinal(5), 1);
    assertEquals(Collatz.getCollatzFinal(10), 1);
    assertEquals(Collatz.getCollatzFinal(21), 1);
  }

}
EOF
}

function test_external_java_target_can_collect_coverage() {
  setup_external_java_target

  bazel coverage --test_output=all @other_repo//:test --combined_report=lcov \
   --instrumentation_filter=// &>$TEST_log \
      || echo "Coverage for //:test failed"

  local coverage_file_path="$(get_coverage_file_path_from_test_log)"
  local expected_result_math='SF:src/main/com/example/Math.java
FN:3,com/example/Math::<init> ()V
FN:6,com/example/Math::isEven (I)Z
FNDA:0,com/example/Math::<init> ()V
FNDA:1,com/example/Math::isEven (I)Z
FNF:2
FNH:1
BRDA:6,0,0,1
BRDA:6,0,1,1
BRF:2
BRH:2
DA:3,0
DA:6,1
LH:1
LF:2
end_of_record'
  local expected_result_collatz="SF:external/+local_repository+other_repo/src/main/com/example/Collatz.java
FN:3,com/example/Collatz::<init> ()V
FN:6,com/example/Collatz::getCollatzFinal (I)I
FNDA:0,com/example/Collatz::<init> ()V
FNDA:1,com/example/Collatz::getCollatzFinal (I)I
FNF:2
FNH:1
BRDA:6,0,0,1
BRDA:6,0,1,1
BRDA:9,0,0,1
BRDA:9,0,1,1
BRF:4
BRH:4
DA:3,0
DA:6,1
DA:7,1
DA:9,1
DA:10,1
DA:12,1
LH:5
LF:6
end_of_record"

  assert_coverage_result "$expected_result_math" "$coverage_file_path"
  assert_coverage_result "$expected_result_collatz" "$coverage_file_path"

  assert_coverage_result "$expected_result_math" bazel-out/_coverage/_coverage_report.dat
  assert_coverage_result "$expected_result_collatz" bazel-out/_coverage/_coverage_report.dat
}

function test_external_java_target_coverage_not_collected_by_default() {
  setup_external_java_target

  bazel coverage --test_output=all @other_repo//:test --combined_report=lcov &>$TEST_log \
      || echo "Coverage for //:test failed"

  local coverage_file_path="$(get_coverage_file_path_from_test_log)"
  local expected_result_math='SF:src/main/com/example/Math.java
FN:3,com/example/Math::<init> ()V
FN:6,com/example/Math::isEven (I)Z
FNDA:0,com/example/Math::<init> ()V
FNDA:1,com/example/Math::isEven (I)Z
FNF:2
FNH:1
BRDA:6,0,0,1
BRDA:6,0,1,1
BRF:2
BRH:2
DA:3,0
DA:6,1
LH:1
LF:2
end_of_record'

  assert_coverage_result "$expected_result_math" "$coverage_file_path"
  assert_not_contains "SF:external/+local_repository+other_repo/" "$coverage_file_path"

  assert_coverage_result "$expected_result_math" bazel-out/_coverage/_coverage_report.dat
  assert_not_contains "SF:external/+local_repository+other_repo/" bazel-out/_coverage/_coverage_report.dat
}

run_suite "test tests"
