// 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.exec;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.ActionEnvironment;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactPathResolver;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.actions.SymlinkTreeAction;
import com.google.devtools.build.lib.analysis.actions.SymlinkTreeActionContext;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.OutputService;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Symlinks;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;

/** Unit tests for {@link SymlinkTreeStrategy}. */
@RunWith(JUnit4.class)
public final class SymlinkTreeStrategyTest extends BuildViewTestCase {
  @Test
  public void testArtifactToPathConversion() {
    Artifact artifact = getBinArtifactWithNoOwner("dir/foo");
    assertThat(SymlinkTreeStrategy.TO_PATH.apply(artifact))
        .isEqualTo(artifact.getPath().asFragment());
    assertThat(SymlinkTreeStrategy.TO_PATH.apply(null)).isEqualTo(null);
  }

  @Test
  public void outputServiceInteraction() throws Exception {
    ActionExecutionContext context = mock(ActionExecutionContext.class);
    OutputService outputService = mock(OutputService.class);
    StoredEventHandler eventHandler = new StoredEventHandler();

    when(context.getContext(SymlinkTreeActionContext.class))
        .thenReturn(new SymlinkTreeStrategy(outputService, null));
    when(context.getInputPath(any())).thenAnswer((i) -> ((Artifact) i.getArgument(0)).getPath());
    when(context.getPathResolver()).thenReturn(ArtifactPathResolver.IDENTITY);
    when(context.getEventHandler()).thenReturn(eventHandler);
    when(outputService.canCreateSymlinkTree()).thenReturn(true);

    Artifact inputManifest = getBinArtifactWithNoOwner("dir/manifest.in");
    Artifact outputManifest = getBinArtifactWithNoOwner("dir.runfiles/MANIFEST");
    Artifact runfile = getBinArtifactWithNoOwner("dir/runfile");
    doAnswer(
            (i) -> {
              outputManifest.getPath().getParentDirectory().createDirectoryAndParents();
              return null;
            })
        .when(outputService)
        .createSymlinkTree(any(), any());

    Runfiles runfiles =
        new Runfiles.Builder("TESTING", false)
            .setEmptyFilesSupplier((paths) -> ImmutableList.of(PathFragment.create("dir/empty")))
            .addArtifact(runfile)
            .build();
    SymlinkTreeAction action =
        new SymlinkTreeAction(
            ActionsTestUtil.NULL_ACTION_OWNER,
            inputManifest,
            runfiles,
            outputManifest,
            /*filesetRoot=*/ null,
            ActionEnvironment.EMPTY,
            /*enableRunfiles=*/ true,
            /*inprocessSymlinkCreation=*/ false,
            /*skipRunfilesManifests=*/ false);

    action.execute(context);

    @SuppressWarnings("unchecked")
    ArgumentCaptor<Map<PathFragment, PathFragment>> capture = ArgumentCaptor.forClass(Map.class);
    verify(outputService, times(1)).createSymlinkTree(capture.capture(), any());
    assertThat(capture.getValue())
        .containsExactly(
            PathFragment.create("TESTING/dir/runfile"),
            runfile.getPath().asFragment(),
            PathFragment.create("TESTING/dir/empty"),
            null);
  }

  @Test
  public void inprocessSymlinkCreation() throws Exception {
    ActionExecutionContext context = mock(ActionExecutionContext.class);
    OutputService outputService = mock(OutputService.class);
    StoredEventHandler eventHandler = new StoredEventHandler();

    when(context.getContext(SymlinkTreeActionContext.class))
        .thenReturn(new SymlinkTreeStrategy(outputService, null));
    when(context.getInputPath(any())).thenAnswer((i) -> ((Artifact) i.getArgument(0)).getPath());
    when(context.getEventHandler()).thenReturn(eventHandler);
    when(outputService.canCreateSymlinkTree()).thenReturn(false);

    Artifact inputManifest = getBinArtifactWithNoOwner("dir/manifest.in");
    Artifact outputManifest = getBinArtifactWithNoOwner("dir.runfiles/MANIFEST");
    Artifact runfile = getBinArtifactWithNoOwner("dir/runfile");

    Runfiles runfiles =
        new Runfiles.Builder("TESTING", false)
            .setEmptyFilesSupplier((paths) -> ImmutableList.of(PathFragment.create("dir/empty")))
            .addArtifact(runfile)
            .build();
    SymlinkTreeAction action =
        new SymlinkTreeAction(
            ActionsTestUtil.NULL_ACTION_OWNER,
            inputManifest,
            runfiles,
            outputManifest,
            /*filesetRoot=*/ null,
            ActionEnvironment.EMPTY,
            /*enableRunfiles=*/ true,
            /*inprocessSymlinkCreation=*/ true,
            /*skipRunfilesManifests*/ false);

    action.execute(context);
    // Check that the OutputService is not used.
    verify(outputService, never()).createSymlinkTree(any(), any());

    Path p = outputManifest.getPath().getParentDirectory().getRelative("TESTING/dir/runfile");
    assertWithMessage("Path %s expected to exist", p).that(p.exists(Symlinks.NOFOLLOW)).isTrue();
    assertWithMessage("Path %s expected to be a symlink", p).that(p.isSymbolicLink()).isTrue();
    assertThat(p.readSymbolicLink()).isEqualTo(runfile.getPath().asFragment());
    Path q = outputManifest.getPath().getParentDirectory().getRelative("TESTING/dir/empty");
    assertWithMessage("Path %s expected to be a file", q).that(q.isFile()).isTrue();
    assertThat(FileSystemUtils.readContent(q)).isEmpty();
  }
}
