// Copyright 2019 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.

package com.google.devtools.build.lib.outputfilter;

import static org.junit.Assert.fail;

import com.google.common.base.Joiner;
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
import com.google.devtools.build.lib.buildtool.util.TestWorkspaceStatusModule;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventCollector;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.BlazeRuntime;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.testutil.Suite;
import com.google.devtools.build.lib.testutil.TestSpec;
import com.google.devtools.build.lib.vfs.Path;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for the {@code --output_filter} option. */
@TestSpec(size = Suite.MEDIUM_TESTS)
@RunWith(JUnit4.class)
public class OutputFilterTest extends BuildIntegrationTestCase {
  private EventCollector stderr = new EventCollector(EventKind.STDERR);
  private Path workspaceScript;

  // Cast warnings are silenced by default.
  private void enableCastWarnings() throws Exception {
    addOptions("--javacopt=\"-Xlint:cast\"");
  }

  // Deprecation warnings are silenced by default.
  private void enableDeprecationWarnings() throws Exception {
    addOptions("--javacopt=\"-Xlint:deprecation\"");
  }

  @Override
  protected BlazeModule getBuildInfoModule() {
    return TestWorkspaceStatusModule.getModule();
  }

  @Override
  protected BlazeRuntime.Builder getRuntimeBuilder() throws Exception {
    return super.getRuntimeBuilder().addBlazeModule(new OutputFilteringModule());
  }

  @Before
  public final void writeFiles() throws Exception  {
    write("java/a/BUILD",
        "java_library(name = 'a',",
        "            srcs = ['A.java']," +
        "            deps = ['//java/b'])");
    write("java/a/A.java",
        "package a;",
        "public class A {",
        "  public static void a() { b.B.b(); }",
        "}");
    write("java/b/BUILD",
        "java_library(name = 'b',",
        "             srcs = ['B.java']," +
        "             deps = ['//java/c'])");
    write("java/b/B.java",
        "package b;",
        "public class B {",
        "  @Deprecated public static void b() {}",
        "  public static void x() { c.C.c(); }",
        "}");
    write("java/c/BUILD",
        "java_library(name = 'c',",
        "             srcs = ['C.java'])");
    write("java/c/C.java",
        "package c;",
        "public class C {",
        "  @Deprecated public static void c() {}",
        "}");
    write("java/d/BUILD",
        "java_library(name = 'd',",
        "             srcs = ['D.java'],",
        "             deps = ['//java/e'])");
    write(
        "java/d/D.java",
        "package d;",
        "import java.lang.Integer;",
        "import java.util.ArrayList;",
        "public class D {",
        "  public static void d() {",
        "    int i = (int) 0;",
        "    e.E.e();",
        "  }",
        "}");
    write("java/e/BUILD",
        "java_library(name = 'e',",
        "             srcs = ['E.java'])");
    write(
        "java/e/E.java",
        "package e;",
        "import java.lang.Integer;",
        "import java.util.LinkedList;",
        "public class E {",
        "  public static void e() {",
        "    int i = (int) 0;",
        "  }",
        "}");
    write("javatests/a/BUILD",
        "java_library(name = 'a',",
        "             srcs = ['ATest.java']," +
        "             deps = ['//java/a', '//javatests/b'])");
    write("javatests/a/ATest.java",
        "package a;",
        "public class ATest {",
        "  public static void aTest() { a.A.a(); }",
        "}");
    write("javatests/b/BUILD",
        "java_library(name = 'b',",
        "             srcs = ['BTest.java']," +
        "             deps = ['//java/b', '//javatests/c'])");
    write("javatests/b/BTest.java",
        "package b;",
        "public class BTest {",
        "  public static void bTest() { c.CTest.c(); }",
        "}");
    write("javatests/c/BUILD",
        "java_library(name = 'c',",
        "             srcs = ['CTest.java'])");
    write("javatests/c/CTest.java",
        "package c;",
        "public class CTest {",
        "  @Deprecated public static void c() {}",
        "}");
    write("javatests/d/BUILD",
        "java_library(name = 'd',",
        "             srcs = ['DTest.java'],",
        "             deps = ['//java/d', '//javatests/e'])");
    write("javatests/d/DTest.java",
        "package d;",
        "public class DTest {",
        "  public static void dTest() { d.D.d(); }",
        "}");
    write("javatests/e/BUILD",
        "java_library(name = 'e',",
        "             srcs = ['ETest.java'])");
    write(
        "javatests/e/ETest.java",
        "package e;",
        "import java.lang.Integer;",
        "import java.util.LinkedList;",
        "public class ETest {",
        "  public static void eTest() {",
        "    int i = (int) 0;",
        "  }",
        "}");
    workspaceScript = write("wrk", "echo STATUS_CMD_HAS_RUN >&2");
    workspaceScript.setExecutable(true);

    // Always enable cast warnings.
    enableCastWarnings();
  }

  @Test
  public void testExplicitFilter() throws Exception {
    enableDeprecationWarnings();
    addOptions("--output_filter=^//java/a");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/a");

    assertEvent(deprecationMessages("b", "B", "b"));
    assertNoEvent(deprecationMessages("c", "C", "c"));
  }

  @Test
  public void testExplicitFilterNoJavacoptOverride() throws Exception {
    addOptions("--output_filter=^//java/d");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/d");

    assertEvent("D.java:6: warning: [cast] redundant cast to int");
    assertNoEvent("E.java:6: warning: [cast] redundant cast to int");
  }

  @Test
  public void testPackagesAOF_A() throws Exception {
    enableDeprecationWarnings();
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/a");

    assertEvent(deprecationMessages("b", "B", "b"));
    assertNoEvent(deprecationMessages("c", "C", "c"));
  }

  @Test
  public void testPackagesAOF_B() throws Exception {
    enableDeprecationWarnings();
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/b");

    assertNoEvent(deprecationMessages("b", "B", "b"));
    assertEvent(deprecationMessages("c", "C", "c"));
  }

  @Test
  public void testPackagesAOF_C() throws Exception {
    enableDeprecationWarnings();
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/c");

    assertNoEvent(deprecationMessages("b", "B", "b"));
    assertNoEvent(deprecationMessages("c", "C", "c"));
  }

  @Test
  public void testPackagesAOF_D() throws Exception {
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/d");

    assertEvent("D.java:6: warning: [cast] redundant cast to int");
    assertNoEvent("E.java:6: warning: [cast] redundant cast to int");
  }

  @Test
  public void testPackagesAOF_AB() throws Exception {
    enableDeprecationWarnings();
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/a", "//java/b");

    assertEvent(deprecationMessages("b", "B", "b"));
    assertEvent(deprecationMessages("c", "C", "c"));
  }

  @Test
  public void testPackagesAOF_AC() throws Exception {
    enableDeprecationWarnings();
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/a", "//java/c");

    assertEvent(deprecationMessages("b", "B", "b"));
    assertNoEvent(deprecationMessages("c", "C", "c"));
  }

  @Test
  public void testPackagesAOF_BC() throws Exception {
    enableDeprecationWarnings();
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/b", "//java/c");

    assertNoEvent(deprecationMessages("b", "B", "b"));
    assertEvent(deprecationMessages("c", "C", "c"));
  }

  @Test
  public void testPackagesAOF_ABC() throws Exception {
    enableDeprecationWarnings();
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/a", "//java/b", "//java/c");

    assertEvent(deprecationMessages("b", "B", "b"));
    assertEvent(deprecationMessages("c", "C", "c"));
  }

  @Test
  public void testPackagesAOF_JavaTestsA() throws Exception {
    enableDeprecationWarnings();
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//javatests/a");

    assertEvent(deprecationMessages("b", "B", "b"));
    assertNoEvent(deprecationMessages("c", "C", "c"));
    assertNoEvent(deprecationMessages("c", "CTest", "c"));
  }

  @Test
  public void testPackagesAOF_JavaTestsAB() throws Exception {
    enableDeprecationWarnings();
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//javatests/a", "//java/b");

    assertEvent(deprecationMessages("b", "B", "b"));
    assertEvent(deprecationMessages("c", "C", "c"));
    assertEvent(deprecationMessages("c", "CTest", "c"));
  }

  @Test
  public void testPackagesAOF_JavaTestsD() throws Exception {
    addOptions("--auto_output_filter=packages");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//javatests/d");

    assertEvent("D.java:6: warning: [cast] redundant cast to int");
    assertNoEvent("E.java:6: warning: [cast] redundant cast to int");
    assertNoEvent("ETest.java:6: warning: [cast] redundant cast to int");
  }

  @Test
  public void testStatusCmdPrinted() throws Exception {
    addOptions("--auto_output_filter=packages",
               "--workspace_status_command=" + workspaceScript.getPathString());
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//javatests/a", "//java/b");
    assertEvent("STATUS_CMD_HAS_RUN");

    addOptions("--auto_output_filter=subpackages",
               "--workspace_status_command=" + workspaceScript.getPathString());
    env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//javatests/a", "//java/b");
    assertEvent("STATUS_CMD_HAS_RUN");
  }

  @Test
  public void testEmptyFilter() throws Exception {
    enableDeprecationWarnings();
    addOptions("--output_filter=");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/a");

    assertEvent(deprecationMessages("b", "B", "b"));
    assertEvent(deprecationMessages("c", "C", "c"));
  }

  @Test
  public void testNoMatchFilter() throws Exception {
    enableDeprecationWarnings();
    addOptions("--output_filter=DONT_MATCH");
    CommandEnvironment env = runtimeWrapper.newCommand();
    env.getReporter().addHandler(stderr);
    buildTarget("//java/a");

    assertNoEvent(deprecationMessages("b", "B", "b"));
    assertNoEvent(deprecationMessages("c", "C", "c"));
  }

  private void assertEvent(String... choices) {
    for (Event event : stderr) {
      for (String msg : choices) {
        if (event.getMessage().contains(msg)) {
          return;
        }
      }
    }

    fail(String.format("Expected one of [%s] in output: %s",
        Joiner.on(',').join(choices),
        Joiner.on('\n').join(stderr)
        ));
  }

  private void assertNoEvent(String... choices) {
    for (Event event : stderr) {
      for (String msg : choices) {
        if (event.getMessage().contains(msg)) {
          fail("Event '" + msg + "' was found in output: \n" + Joiner.on('\n').join(stderr));
        }
      }
    }
  }

  private String[] deprecationMessages(String pkg, String clazz, String method) {
    return new String[] {
        String.format("%s() in %s.%s has been deprecated", method, pkg, clazz), // javac6
        String.format("%s() in %s has been deprecated", method, clazz) // javac7
    };
  }
}
