// Copyright 2006 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.filegroup;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.OutputGroupInfo;
import com.google.devtools.build.lib.analysis.configuredtargets.FileConfiguredTarget;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.rules.java.JavaSemantics;
import com.google.devtools.build.lib.util.FileType;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link Filegroup}.
 */
@RunWith(JUnit4.class)
public class FilegroupConfiguredTargetTest extends BuildViewTestCase {

  @Test
  public void testGroup() throws Exception {
    scratch.file(
        "nevermore/BUILD",
        """
        filegroup(name  = 'staticdata',
                  srcs = ['staticdata/spam.txt', 'staticdata/good.txt'])
        """);
    ConfiguredTarget groupTarget = getConfiguredTarget("//nevermore:staticdata");
    assertThat(ActionsTestUtil.prettyArtifactNames(getFilesToBuild(groupTarget)))
        .containsExactly("nevermore/staticdata/spam.txt", "nevermore/staticdata/good.txt");
  }

  @Test
  public void testDependencyGraph() throws Exception {
    scratch.file(
        "java/com/google/test/BUILD",
        """
        java_binary(name  = 'test_app',
            resources = [':data'],
            create_executable = 0,
            srcs  = ['InputFile.java', 'InputFile2.java'])
        filegroup(name  = 'data',
                  srcs = ['b.txt', 'a.txt'])
        """);
    FileConfiguredTarget appOutput =
        getFileConfiguredTarget("//java/com/google/test:test_app.jar");
    assertThat(actionsTestUtil().predecessorClosureOf(appOutput.getArtifact(), FileType.of(".txt")))
        .isEqualTo("b.txt a.txt");
  }

  @Test
  public void testEmptyGroupIsAnOk() throws Exception {
    scratchConfiguredTarget("empty", "empty",
        "filegroup(name='empty', srcs=[])");
  }

  @Test
  public void testEmptyGroupInGenruleIsOk() throws Exception {
    scratchConfiguredTarget("empty", "genempty",
        "filegroup(name='empty', srcs=[])",
        "genrule(name='genempty', tools=[':empty'], outs=['nothing'], cmd='touch $@')");
  }

  private void writeTest() throws IOException {
    scratch.file(
        "another/BUILD",
        """
        filegroup(name  = 'another',
                  srcs = ['another.txt'])
        """);
    scratch.file(
        "test/BUILD",
        """
        filegroup(name  = 'a',
                  srcs = ['a.txt'])
        filegroup(name  = 'b',
                  srcs = ['a.txt'])
        filegroup(name  = 'c',
                  srcs = ['a', 'b.txt'])
        filegroup(name  = 'd',
                  srcs = ['//another:another.txt'])
        """);
  }

  @Test
  public void testFileCanBeSrcsOfMultipleRules() throws Exception {
    writeTest();
    assertThat(
            ActionsTestUtil.prettyArtifactNames(getFilesToBuild(getConfiguredTarget("//test:a"))))
        .containsExactly("test/a.txt");
    assertThat(
            ActionsTestUtil.prettyArtifactNames(getFilesToBuild(getConfiguredTarget("//test:b"))))
        .containsExactly("test/a.txt");
  }

  @Test
  public void testRuleCanBeSrcsOfOtherRule() throws Exception {
    writeTest();
    assertThat(
            ActionsTestUtil.prettyArtifactNames(getFilesToBuild(getConfiguredTarget("//test:c"))))
        .containsExactly("test/a.txt", "test/b.txt");
  }

  @Test
  public void testOtherPackageCanBeSrcsOfRule() throws Exception {
    writeTest();
    assertThat(
            ActionsTestUtil.prettyArtifactNames(getFilesToBuild(getConfiguredTarget("//test:d"))))
        .containsExactly("another/another.txt");
  }

  @Test
  public void testIsNotExecutable() throws Exception {
    scratch.file("x/BUILD",
                "filegroup(name = 'not_exec_two_files', srcs = ['bin', 'bin.sh'])");
    assertThat(getExecutable("//x:not_exec_two_files")).isNull();
  }

  @Test
  public void testIsExecutable() throws Exception {
    scratch.file("x/BUILD",
                "filegroup(name = 'exec', srcs = ['bin'])");
    assertThat(getExecutable("//x:exec").getExecPath().getPathString()).isEqualTo("x/bin");
  }

  @Test
  public void testNoDuplicate() throws Exception {
    scratch.file(
        "x/BUILD",
        """
        filegroup(name = 'a', srcs = ['file'])
        filegroup(name = 'b', srcs = ['file'])
        filegroup(name = 'c', srcs = [':a', ':b'])
        """);
    assertThat(ActionsTestUtil.prettyArtifactNames(getFilesToBuild(getConfiguredTarget("//x:c"))))
        .containsExactly("x/file");
  }

  @Test
  public void testGlobMatchesRuleOutputsInsteadOfFileWithTheSameName() throws Exception {
    scratch.file("pkg/file_or_rule");
    scratch.file("pkg/a.txt");
    ConfiguredTarget target = scratchConfiguredTarget("pkg", "my_rule",
                "filegroup(name = 'file_or_rule', srcs = ['a.txt'])",
                "filegroup(name = 'my_rule', srcs = glob(['file_or_rule']))");
    assertThat(ActionsTestUtil.baseArtifactNames(getFilesToBuild(target))).containsExactly("a.txt");
  }

  @Test
  public void outputGroupSourceJars_extractsTransitiveSources() throws Exception {
    scratch.file("pkg/a.java");
    scratch.file("pkg/b.java");
    scratch.file("pkg/c.java");
    scratch.file(
        "pkg/BUILD",
        "java_library(name='lib_a', srcs=['a.java'])",
        "java_library(name='lib_b', srcs=['b.java'], deps = [':lib_c'])",
        "java_library(name='lib_c', srcs=['c.java'])",
        "filegroup(name='group', srcs=[':lib_a', ':lib_b'],"
            + String.format("output_group='%s')", JavaSemantics.SOURCE_JARS_OUTPUT_GROUP));

    ConfiguredTarget group = getConfiguredTarget("//pkg:group");

    assertThat(ActionsTestUtil.prettyArtifactNames(getFilesToBuild(group)))
        .containsExactly("pkg/liblib_a-src.jar", "pkg/liblib_b-src.jar", "pkg/liblib_c-src.jar");
  }

  @Test
  public void outputGroupDirectSourceJars_extractsDirectSources() throws Exception {
    scratch.file("pkg/a.java");
    scratch.file("pkg/b.java");
    scratch.file("pkg/c.java");
    scratch.file(
        "pkg/BUILD",
        "java_library(name='lib_a', srcs=['a.java'])",
        "java_library(name='lib_b', srcs=['b.java'], deps = [':lib_c'])",
        "java_library(name='lib_c', srcs=['c.java'])",
        "filegroup(name='group', srcs=[':lib_a', ':lib_b'],"
            + String.format("output_group='%s')", JavaSemantics.DIRECT_SOURCE_JARS_OUTPUT_GROUP));

    ConfiguredTarget group = getConfiguredTarget("//pkg:group");

    assertThat(ActionsTestUtil.prettyArtifactNames(getFilesToBuild(group)))
        .containsExactly("pkg/liblib_a-src.jar", "pkg/liblib_b-src.jar");
  }

  @Test
  public void testErrorForIllegalOutputGroup() throws Exception {
    scratch.file("pkg/a.cc");
    scratch.file(
        "pkg/BUILD",
        "cc_library(name='lib_a', srcs=['a.cc'])",
        String.format(
            "filegroup(name='group', srcs=[':lib_a'], output_group='%s')",
            OutputGroupInfo.HIDDEN_TOP_LEVEL));
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//pkg:group"));
    assertThat(e)
        .hasMessageThat()
        .contains(
            String.format(Filegroup.ILLEGAL_OUTPUT_GROUP_ERROR, OutputGroupInfo.HIDDEN_TOP_LEVEL));
  }
}
