// Copyright 2018 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.skyframe;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;

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.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.skyframe.TransitiveBaseTraversalFunction.TargetAndErrorIfAnyImpl;
import com.google.devtools.build.lib.syntax.SkylarkSemantics;
import com.google.devtools.build.lib.util.GroupedList;
import com.google.devtools.build.lib.util.GroupedList.GroupedListHelper;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyKey;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;

/** Test for {@link TransitiveTraversalFunction}. */
@RunWith(JUnit4.class)
public class TransitiveTraversalFunctionTest extends BuildViewTestCase {

  @Test
  public void noRepeatedLabelVisitationForTransitiveTraversalFunction() throws Exception {
    // Create a basic package with a target //foo:foo.
    Label label = Label.parseAbsolute("//foo:foo", ImmutableMap.of());
    Package pkg =
        scratchPackage(
            "workspace",
            label.getPackageIdentifier(),
            "sh_library(name = '" + label.getName() + "')");
    TargetAndErrorIfAnyImpl targetAndErrorIfAny =
        new TargetAndErrorIfAnyImpl(
            /*packageLoadedSuccessfully=*/ true,
            /*errorLoadingTarget=*/ null,
            pkg.getTarget(label.getName()));
    TransitiveTraversalFunction function =
        new TransitiveTraversalFunction() {
          @Override
          LoadTargetResults loadTarget(Environment env, Label label) {
            return targetAndErrorIfAny;
          }
        };
    // Create the GroupedList saying we had already requested two targets the last time we called
    // #compute.
    GroupedListHelper<SkyKey> helper = new GroupedListHelper<>();
    SkyKey fakeDep1 = function.getKey(Label.parseAbsolute("//foo:bar", ImmutableMap.of()));
    SkyKey fakeDep2 = function.getKey(Label.parseAbsolute("//foo:baz", ImmutableMap.of()));
    helper.add(TargetMarkerValue.key(label));
    helper.add(PackageValue.key(label.getPackageIdentifier()));
    helper.startGroup();
    // Note that these targets don't actually exist in the package we created initially. It doesn't
    // matter for the purpose of this test, the original package was just to create some objects
    // that we needed.
    helper.add(fakeDep1);
    helper.add(fakeDep2);
    helper.endGroup();
    GroupedList<SkyKey> groupedList = new GroupedList<>();
    groupedList.append(helper);
    AtomicBoolean wasOptimizationUsed = new AtomicBoolean(false);
    SkyFunction.Environment mockEnv = Mockito.mock(SkyFunction.Environment.class);
    when(mockEnv.getTemporaryDirectDeps()).thenReturn(groupedList);
    when(mockEnv.getValuesOrThrow(
            groupedList.get(2), NoSuchPackageException.class, NoSuchTargetException.class))
        .thenAnswer(
            (invocationOnMock) -> {
              wasOptimizationUsed.set(true);
              // It doesn't matter what this map is, we'll return false in the valuesMissing() call.
              return ImmutableMap.of();
            });
    when(mockEnv.valuesMissing()).thenReturn(true);

    // Run the compute function and check that we returned null.
    assertThat(function.compute(function.getKey(label), mockEnv)).isNull();

    // Verify that the mock was called with the arguments we expected.
    assertThat(wasOptimizationUsed.get()).isTrue();
  }

  private Package scratchPackage(String workspaceName, PackageIdentifier packageId, String... lines)
      throws Exception {
    Path buildFile = scratch.file("" + packageId.getSourceRoot() + "/BUILD", lines);
    Package.Builder externalPkg =
        Package.newExternalPackageBuilder(
            Package.Builder.DefaultHelper.INSTANCE,
            RootedPath.toRootedPath(root, buildFile.getRelative("WORKSPACE")),
            "TESTING");
    externalPkg.setWorkspaceName(workspaceName);
    return pkgFactory.createPackageForTesting(
        packageId,
        externalPkg.build(),
        RootedPath.toRootedPath(root, buildFile),
        packageIdentifier -> buildFile,
        reporter,
        SkylarkSemantics.DEFAULT_SEMANTICS);
  }
}
