// 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.rules.python;

import static com.google.common.truth.Truth.assertThat;

import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.testutil.TestConstants;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@code <tools repo>//tools/python:srcs_version.bzl%find_requirements}. */
@RunWith(JUnit4.class)
public class PythonSrcsVersionAspectTest extends BuildViewTestCase {

  private static String join(String... args) {
    return String.join("\n", args);
  }

  /**
   * Returns the contents of the {@code -pyversioninfo.txt} file that would be produced by running
   * the aspect on the given target.
   */
  private String evaluateAspectFor(String label) throws Exception {
    scratch.file(
        "asp/BUILD",
        "load('" + TestConstants.TOOLS_REPOSITORY + "//tools/python:srcs_version.bzl', ",
        "     'apply_find_requirements_for_testing')",
        "apply_find_requirements_for_testing(",
        "    name = 'asp',",
        "    target = '" + label + "',",
        "    out = 'out',",
        ")");
    ConfiguredTarget ct = getConfiguredTarget("//asp");
    assertThat(ct).isNotNull();
    Artifact out = getBinArtifact("out", ct);
    Action action = getGeneratingAction(out);
    assertThat(action).isInstanceOf(FileWriteAction.class);
    return ((FileWriteAction) action).getFileContents();
  }

  @Test
  public void simpleCase() throws Exception {
    PythonTestUtils.assumeIsBazel(); // Google has py2 disabled.
    setBuildLanguageOptions(
        "--experimental_builtins_injection_override=-py_test,-py_binary,-py_library");
    scratch.file(
        "pkg/BUILD",
        "py_library(",
        "    name = 'lib',",
        "    srcs = ['lib.py'],",
        "    srcs_version = 'PY3ONLY',",
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':lib'],",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "<None>",
            "",
            "Python 3-only deps:",
            "@//pkg:lib",
            "",
            "Paths to these deps:",
            "@//pkg:bin -> @//pkg:lib",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void noRequirements() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "py_library(",
        "    name = 'lib',",
        "    srcs = ['lib.py'],",
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':lib'],",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "<None>",
            "",
            "Python 3-only deps:",
            "<None>",
            "",
            "Paths to these deps:",
            "<None>",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void twoContradictoryRequirements() throws Exception {
    PythonTestUtils.assumeIsBazel(); // Google has py2 disabled.
    setBuildLanguageOptions(
        "--experimental_builtins_injection_override=-py_test,-py_binary,-py_library");
    scratch.file(
        "pkg/BUILD",
        "py_library(",
        "    name = 'lib2',",
        "    srcs = ['lib.py'],",
        "    srcs_version = 'PY2ONLY',",
        ")",
        "py_library(",
        "    name = 'lib3',",
        "    srcs = ['lib.py'],",
        "    srcs_version = 'PY3',", // PY3 should be same as PY3ONLY
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':lib2', ':lib3'],",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "@//pkg:lib2",
            "",
            "Python 3-only deps:",
            "@//pkg:lib3",
            "",
            "Paths to these deps:",
            "@//pkg:bin -> @//pkg:lib2",
            "@//pkg:bin -> @//pkg:lib3",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void toplevelSelfContradictory() throws Exception {
    PythonTestUtils.assumeIsBazel(); // Google has py2 disabled.
    setBuildLanguageOptions(
        "--experimental_builtins_injection_override=-py_test,-py_binary,-py_library");
    scratch.file(
        "pkg/BUILD",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    srcs_version = 'PY3ONLY',",
        "    python_version = 'PY2',",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "<None>",
            "",
            "Python 3-only deps:",
            "@//pkg:bin",
            "",
            "Paths to these deps:",
            "@//pkg:bin",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void indirectDependencies() throws Exception {
    PythonTestUtils.assumeIsBazel(); // Google has py2 disabled.
    setBuildLanguageOptions(
        "--experimental_builtins_injection_override=-py_test,-py_binary,-py_library");
    // A <- B <- C <- bin, where only B has the constraint.
    scratch.file(
        "pkg/BUILD",
        "py_library(",
        "    name = 'libA',",
        "    srcs = ['libA.py'],",
        ")",
        "py_library(",
        "    name = 'libB',",
        "    srcs = ['libB.py'],",
        "    deps = [':libA'],",
        "    srcs_version = 'PY3ONLY',",
        ")",
        "py_library(",
        "    name = 'libC',",
        "    srcs = ['libC.py'],",
        "    deps = [':libB'],",
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':libC'],",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "<None>",
            "",
            "Python 3-only deps:",
            "@//pkg:libB",
            "",
            "Paths to these deps:",
            "@//pkg:bin -> @//pkg:libC -> @//pkg:libB",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void onlyReportTopmost() throws Exception {
    PythonTestUtils.assumeIsBazel(); // Google has py2 disabled.
    setBuildLanguageOptions(
        "--experimental_builtins_injection_override=-py_test,-py_binary,-py_library");
    // A <- B <- C <- bin, where A and C have the constraint.
    scratch.file(
        "pkg/BUILD",
        "py_library(",
        "    name = 'libA',",
        "    srcs = ['libA.py'],",
        "    srcs_version = 'PY3ONLY',",
        ")",
        "py_library(",
        "    name = 'libB',",
        "    srcs = ['libB.py'],",
        "    deps = [':libA'],",
        ")",
        "py_library(",
        "    name = 'libC',",
        "    srcs = ['libC.py'],",
        "    deps = [':libB'],",
        "    srcs_version = 'PY3ONLY',",
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':libC'],",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "<None>",
            "",
            "Python 3-only deps:",
            "@//pkg:libC",
            "",
            "Paths to these deps:",
            "@//pkg:bin -> @//pkg:libC",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void oneTopmostReachesAnother() throws Exception {
    PythonTestUtils.assumeIsBazel(); // Google has py2 disabled.
    setBuildLanguageOptions(
        "--experimental_builtins_injection_override=-py_test,-py_binary,-py_library");
    // A <- B <- C, where A and C have the constraint.
    // A <- bin and C <- bin, so both A and C are top-most even though C has a path to A.
    scratch.file(
        "pkg/BUILD",
        "py_library(",
        "    name = 'libA',",
        "    srcs = ['libA.py'],",
        "    srcs_version = 'PY3ONLY',",
        ")",
        "py_library(",
        "    name = 'libB',",
        "    srcs = ['libB.py'],",
        "    deps = [':libA'],",
        ")",
        "py_library(",
        "    name = 'libC',",
        "    srcs = ['libC.py'],",
        "    deps = [':libB'],",
        "    srcs_version = 'PY3ONLY',",
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':libA', ':libC'],",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "<None>",
            "",
            "Python 3-only deps:",
            "@//pkg:libA",
            "@//pkg:libC",
            "",
            "Paths to these deps:",
            "@//pkg:bin -> @//pkg:libA",
            "@//pkg:bin -> @//pkg:libC",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void multiplePathsToRequirement() throws Exception {
    PythonTestUtils.assumeIsBazel(); // Google has py2 disabled.
    setBuildLanguageOptions(
        "--experimental_builtins_injection_override=-py_test,-py_binary,-py_library");
    // Diamond graph A <- B, A <- C, B <- bin, C <- bin, where only A has the constraint.
    // A is reached through two different paths but reported only once.
    scratch.file(
        "pkg/BUILD",
        "py_library(",
        "    name = 'libA',",
        "    srcs = ['libA.py'],",
        "    srcs_version = 'PY3ONLY',",
        ")",
        "py_library(",
        "    name = 'libB',",
        "    srcs = ['libB.py'],",
        "    deps = [':libA'],",
        ")",
        "py_library(",
        "    name = 'libC',",
        "    srcs = ['libC.py'],",
        "    deps = [':libA'],",
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':libB', ':libC'],",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "<None>",
            "",
            "Python 3-only deps:",
            "@//pkg:libA",
            "",
            "Paths to these deps:",
            "@//pkg:bin -> @//pkg:libB -> @//pkg:libA",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void noSrcsVersionButIntroducesRequirement() throws Exception {
    PythonTestUtils.assumeIsBazel(); // Google has py2 disabled.
    setBuildLanguageOptions(
        "--experimental_builtins_injection_override=-py_test,-py_binary,-py_library");
    // A <- B <- C <- bin, B introduces the requirement but not via srcs_version.
    // dummy_rule propagates sources and sets the py3-only bit.
    scratch.file(
        "pkg/rules.bzl",
        "def _dummy_rule_impl(ctx):",
        "    info = PyInfo(",
        "        transitive_sources = depset(",
        "            transitive=[d[PyInfo].transitive_sources for d in ctx.attr.deps],",
        "            order='postorder'),",
        "        has_py3_only_sources = True)",
        "    return [info]",
        "dummy_rule = rule(",
        "    implementation = _dummy_rule_impl,",
        "    attrs = {'deps': attr.label_list()},",
        ")");
    scratch.file(
        "pkg/BUILD",
        "load(':rules.bzl', 'dummy_rule')",
        "py_library(",
        "    name = 'libA',",
        "    srcs = ['libA.py'],",
        ")",
        "dummy_rule(",
        "    name = 'libB',",
        "    deps = [':libA'],",
        ")",
        "dummy_rule(",
        "    name = 'libC',",
        "    deps = [':libB'],",
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':libC'],",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "<None>",
            "",
            "Python 3-only deps:",
            "@//pkg:libB",
            "",
            "Paths to these deps:",
            "@//pkg:bin -> @//pkg:libC -> @//pkg:libB",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void requirementNotPropagated() throws Exception {
    // A <- B <- C <- bin, A introduces the requirement, but B doesn't propagate it.
    // dummy_rule propagates sources but nothing else. It also has a srcs_version attr that is
    // ignored because the provider field is false.
    scratch.file(
        "pkg/rules.bzl",
        "def _dummy_rule_impl(ctx):",
        "    info = PyInfo(",
        "        transitive_sources = depset(",
        "            transitive=[d[PyInfo].transitive_sources for d in ctx.attr.deps],",
        "            order='postorder'))",
        "    return [info]",
        "dummy_rule = rule(",
        "    implementation = _dummy_rule_impl,",
        "    attrs = {",
        "        'deps': attr.label_list(),",
        "        'srcs_version': attr.string(),",
        "    },",
        ")");
    scratch.file(
        "pkg/BUILD",
        "load(':rules.bzl', 'dummy_rule')",
        "py_library(",
        "    name = 'libA',",
        "    srcs = ['libA.py'],",
        "    srcs_version = 'PY3ONLY',",
        ")",
        "dummy_rule(",
        "    name = 'libB',",
        "    deps = [':libA'],",
        "    srcs_version = 'PY3ONLY',",
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':libB'],",
        ")");
    String result = evaluateAspectFor("//pkg:bin");
    String golden =
        join(
            "Python 2-only deps:",
            "<None>",
            "",
            "Python 3-only deps:",
            "<None>",
            "",
            "Paths to these deps:",
            "<None>",
            "");
    assertThat(result).isEqualTo(golden);
  }

  @Test
  public void toleratesTargetsWithoutDepsAttr() throws Exception {
    scratch.file(
        "pkg/rules.bzl",
        "def _dummy_rule_impl(ctx):",
        "    info = PyInfo(transitive_sources = depset([]))",
        "    return [info]",
        "dummy_rule = rule(",
        "    implementation = _dummy_rule_impl,",
        ")");
    scratch.file(
        "pkg/BUILD",
        "load(':rules.bzl', 'dummy_rule')",
        "dummy_rule(",
        "    name = 'lib',",
        ")",
        "py_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.py'],",
        "    deps = [':lib'],",
        ")");
    evaluateAspectFor("//pkg:bin");
  }
}
