// Copyright 2021 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.packages;

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

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.vfs.ModifiedFileSet;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@code native.glob} function. */
@RunWith(JUnit4.class)
public class NativeGlobTest extends BuildViewTestCase {

  @Test
  public void glob_simple() throws Exception {
    makeFile("test/starlark/file1.txt");
    makeFile("test/starlark/file2.txt");
    makeFile("test/starlark/file3.txt");

    makeGlobFilegroup("test/starlark/BUILD", "glob(['*'])");

    assertAttrLabelList(
        "//test/starlark:files",
        "srcs",
        ImmutableList.of(
            "//test/starlark:BUILD",
            "//test/starlark:file1.txt",
            "//test/starlark:file2.txt",
            "//test/starlark:file3.txt"));
  }

  @Test
  public void glob_not_empty() throws Exception {

    makeGlobFilegroup("test/starlark/BUILD", "glob(['foo*'], allow_empty=False)");

    AssertionError e =
        assertThrows(
            AssertionError.class,
            () -> assertAttrLabelList("//test/starlark:files", "srcs", ImmutableList.of()));
    assertThat(e).hasMessageThat().contains("allow_empty");
  }

  @Test
  public void glob_simple_subdirs() throws Exception {
    makeFile("test/starlark/sub/file1.txt");
    makeFile("test/starlark/sub2/file2.txt");
    makeFile("test/starlark/sub3/file3.txt");

    makeGlobFilegroup("test/starlark/BUILD", "glob(['**'])");

    assertAttrLabelList(
        "//test/starlark:files",
        "srcs",
        ImmutableList.of(
            "//test/starlark:BUILD",
            "//test/starlark:sub/file1.txt",
            "//test/starlark:sub2/file2.txt",
            "//test/starlark:sub3/file3.txt"));
  }

  @Test
  public void glob_incremental() throws Exception {
    makeFile("test/starlark/file1.txt");
    makeGlobFilegroup("test/starlark/BUILD", "glob(['**'])");

    assertAttrLabelList(
        "//test/starlark:files",
        "srcs",
        ImmutableList.of("//test/starlark:BUILD", "//test/starlark:file1.txt"));

    scratch.file("test/starlark/file2.txt");
    scratch.file("test/starlark/sub/subfile3.txt");

    // Poke SkyFrame to tell it what changed.
    invalidateSkyFrameFiles(
        "test/starlark", "test/starlark/file2.txt", "test/starlark/sub/subfile3.txt");

    assertAttrLabelList(
        "//test/starlark:files",
        "srcs",
        ImmutableList.of(
            "//test/starlark:BUILD",
            "//test/starlark:file1.txt",
            "//test/starlark:file2.txt",
            "//test/starlark:sub/subfile3.txt"));
  }

  /**
   * Constructs a BUILD file containing a single rule with uses glob() to list files look for a rule
   * called :files in it.
   */
  private void makeGlobFilegroup(String buildPath, String glob) throws IOException {
    scratch.file(buildPath, "filegroup(", "   name = 'files',", "   srcs = " + glob, ")");
  }

  private void assertAttrLabelList(String target, String attrName, List<String> expectedLabels)
      throws Exception {
    ConfiguredTargetAndData cfgTarget = getConfiguredTargetAndData(target);
    assertThat(cfgTarget).isNotNull();

    ImmutableList<Label> labels =
        expectedLabels.stream().map(this::makeLabel).collect(toImmutableList());

    ConfiguredAttributeMapper configuredAttributeMapper =
        getMapperFromConfiguredTargetAndTarget(cfgTarget);
    assertThat(configuredAttributeMapper.get(attrName, BuildType.LABEL_LIST))
        .containsExactlyElementsIn(labels);
  }

  private Label makeLabel(String label) {
    try {
      return Label.parseAbsolute(label, ImmutableMap.of());
    } catch (Exception e) {
      // Always fails the test.
      assertThat(e).isNull();
      return null;
    }
  }

  private void invalidateSkyFrameFiles(String... files) throws Exception {
    ModifiedFileSet.Builder builder = ModifiedFileSet.builder();

    for (String f : files) {
      builder.modify(PathFragment.create(f));
    }

    getSkyframeExecutor()
        .invalidateFilesUnderPathForTesting(
            reporter, builder.build(), Root.fromPath(rootDirectory));
  }

  private void makeFile(String fileName) throws IOException {
    scratch.file(fileName, "Content: " + fileName);
  }
}
