// Copyright 2020 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.mock;
import static org.mockito.Mockito.when;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.ActionLookupData;
import com.google.devtools.build.lib.actions.ActionLookupKey;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.ArchivedTreeArtifact;
import com.google.devtools.build.lib.actions.Artifact.DerivedArtifact;
import com.google.devtools.build.lib.actions.Artifact.OwnerlessArtifactWrapper;
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.actions.ArtifactRoot.RootType;
import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil.NullAction;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.skyframe.TreeArtifactValue.ArchivedRepresentation;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import java.io.IOException;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Tests for {@link ActionExecutionValue#transformForSharedAction} for values including tree
 * artifacts.
 */
@RunWith(TestParameterInjector.class)
public final class ActionExecutionValueTransformSharedTreeArtifactsTest {

  private static final PathFragment DERIVED_PATH_PREFIX = PathFragment.create("bazel-out");

  private static final ActionLookupKey KEY_1 = mock(ActionLookupKey.class);
  private static final ActionLookupKey KEY_2 = mock(ActionLookupKey.class);

  @TestParameter private boolean includeArchivedTreeArtifacts;

  private final Scratch scratch = new Scratch();
  private ArtifactRoot derivedRoot;

  @BeforeClass
  public static void initMocks() {
    when(KEY_1.toKey()).thenReturn(KEY_1);
    when(KEY_2.toKey()).thenReturn(KEY_2);
  }

  @Before
  public void createDerivedRoot() throws IOException {
    derivedRoot =
        ArtifactRoot.asDerivedRoot(scratch.dir("/execroot"), RootType.Output, DERIVED_PATH_PREFIX);
  }

  @Test
  public void transformForSharedAction_createsCopyOfEmptyTreeArtifact() throws Exception {
    SpecialArtifact tree = createTreeArtifact("dir", KEY_1);
    TreeArtifactValue value = createTreeArtifactValue(tree);
    ActionExecutionValue actionExecutionValue =
        createActionExecutionValue(ImmutableMap.of(tree, value));

    SpecialArtifact tree2 = createTreeArtifact("dir", KEY_2);
    ActionExecutionValue transformedValue =
        actionExecutionValue.transformForSharedAction(new NullAction(tree2));

    assertThat(transformedValue.getAllFileValues()).isEmpty();
    assertThat(transformedValue.getAllTreeArtifactValues().keySet()).containsExactly(tree2);
    assertEqualsWithNewParent(value, tree2, transformedValue.getTreeArtifactValue(tree2));
  }

  @Test
  public void transformForSharedAction_createsCopyOfTreeArtifact() throws Exception {
    SpecialArtifact tree = createTreeArtifact("dir", KEY_1);
    TreeArtifactValue value = createTreeArtifactValue(tree, "file1", "file2");
    ActionExecutionValue actionExecutionValue =
        createActionExecutionValue(ImmutableMap.of(tree, value));

    SpecialArtifact tree2 = createTreeArtifact("dir", KEY_2);
    ActionExecutionValue transformedValue =
        actionExecutionValue.transformForSharedAction(new NullAction(tree2));

    assertThat(transformedValue.getAllFileValues()).isEmpty();
    assertThat(transformedValue.getAllTreeArtifactValues().keySet()).containsExactly(tree2);
    assertEqualsWithNewParent(value, tree2, transformedValue.getTreeArtifactValue(tree2));
  }

  @Test
  public void transformForSharedAction_createsCopyOfMultipleTreeArtifacts() throws Exception {
    SpecialArtifact tree1 = createTreeArtifact("dir1", KEY_1);
    SpecialArtifact tree2 = createTreeArtifact("dir2", KEY_1);
    TreeArtifactValue value1 = createTreeArtifactValue(tree1, "file1");
    TreeArtifactValue value2 = createTreeArtifactValue(tree2, "file2", "file3");
    ActionExecutionValue actionExecutionValue =
        createActionExecutionValue(ImmutableMap.of(tree1, value1, tree2, value2));

    SpecialArtifact sharedTree1 = createTreeArtifact("dir1", KEY_2);
    SpecialArtifact sharedTree2 = createTreeArtifact("dir2", KEY_2);
    ActionExecutionValue transformedValue =
        actionExecutionValue.transformForSharedAction(new NullAction(sharedTree1, sharedTree2));

    assertThat(transformedValue.getAllFileValues()).isEmpty();
    assertThat(transformedValue.getAllTreeArtifactValues().keySet())
        .containsExactly(sharedTree1, sharedTree2);
    assertEqualsWithNewParent(
        value1, sharedTree1, transformedValue.getTreeArtifactValue(sharedTree1));
    assertEqualsWithNewParent(
        value2, sharedTree2, transformedValue.getTreeArtifactValue(sharedTree2));
  }

  @Test
  public void transformForSharedAction_createsCopyForFileAndTreeArtifacts() throws Exception {
    DerivedArtifact file = createFileArtifact("file", KEY_1);
    createFile(file.getPath());
    FileArtifactValue fileValue = FileArtifactValue.createForTesting(file);
    SpecialArtifact tree = createTreeArtifact("dir", KEY_1);
    TreeArtifactValue treeValue = createTreeArtifactValue(tree, "file1", "file2");
    ActionExecutionValue actionExecutionValue =
        createActionExecutionValue(
            ImmutableMap.of(file, fileValue), ImmutableMap.of(tree, treeValue));

    SpecialArtifact sharedTree = createTreeArtifact("dir", KEY_2);
    DerivedArtifact sharedFile = createFileArtifact("file", KEY_2);
    ActionExecutionValue transformedValue =
        actionExecutionValue.transformForSharedAction(new NullAction(sharedFile, sharedTree));

    assertThat(transformedValue.getAllFileValues().keySet()).containsExactly(sharedFile);
    assertThat(transformedValue.getAllFileValues().get(sharedFile)).isSameInstanceAs(fileValue);
    assertThat(transformedValue.getAllTreeArtifactValues().keySet()).containsExactly(sharedTree);
    assertEqualsWithNewParent(
        treeValue, sharedTree, transformedValue.getTreeArtifactValue(sharedTree));
  }

  /**
   * Checks that provided {@link TreeArtifactValue} has equal metadata to the original one, expected
   * parent for all of the included artifacts and otherwise the same artifacts as the original one.
   */
  private void assertEqualsWithNewParent(
      TreeArtifactValue originalValue,
      SpecialArtifact expectedTree,
      TreeArtifactValue actualValue) {
    assertThat(actualValue.getDigest()).isEqualTo(originalValue.getDigest());
    assertThat(actualValue.getMetadata()).isEqualTo(originalValue.getMetadata());
    assertThat(actualValue.getChildPaths()).isEqualTo(originalValue.getChildPaths());

    assertThat(actualValue.getArchivedRepresentation().isPresent())
        .isEqualTo(includeArchivedTreeArtifacts);

    actualValue
        .getArchivedRepresentation()
        .ifPresent(
            archivedRepresentation -> {
              ArchivedRepresentation originalRepresentation =
                  originalValue.getArchivedRepresentation().get();
              assertEqualsWithNewParent(
                  originalRepresentation, expectedTree, archivedRepresentation);
            });

    actualValue
        .getChildValues()
        .forEach(
            (artifact, metadata) -> {
              TreeFileArtifact originalArtifact =
                  originalValue.getChildren().stream()
                      .filter(
                          original ->
                              original
                                  .getParentRelativePath()
                                  .equals(artifact.getParentRelativePath()))
                      .findAny()
                      .get();
              assertThat(artifact.getParent()).isEqualTo(expectedTree);
              assertThat(artifact.getGeneratingActionKey())
                  .isEqualTo(expectedTree.getGeneratingActionKey());
              assertOwnerlessEquals(originalArtifact, artifact);
              assertThat(artifact.isChildOfDeclaredDirectory())
                  .isEqualTo(originalArtifact.isChildOfDeclaredDirectory());
              assertThat(metadata)
                  .isSameInstanceAs(originalValue.getChildValues().get(originalArtifact));
            });
  }

  private static void assertEqualsWithNewParent(
      ArchivedRepresentation expectedRepresentation,
      SpecialArtifact expectedTree,
      ArchivedRepresentation actualRepresentation) {
    assertThat(actualRepresentation.archivedTreeFileArtifact().getParent()).isEqualTo(expectedTree);
    assertThat(actualRepresentation.archivedTreeFileArtifact().getGeneratingActionKey())
        .isEqualTo(expectedTree.getGeneratingActionKey());
    assertOwnerlessEquals(
        expectedRepresentation.archivedTreeFileArtifact(),
        actualRepresentation.archivedTreeFileArtifact());
    assertThat(actualRepresentation.archivedFileValue())
        .isSameInstanceAs(expectedRepresentation.archivedFileValue());
  }

  private static void assertOwnerlessEquals(Artifact expectedArtifact, Artifact actualArtifact) {
    assertThat(new OwnerlessArtifactWrapper(actualArtifact))
        .isEqualTo(new OwnerlessArtifactWrapper(expectedArtifact));
  }

  private TreeArtifactValue createTreeArtifactValue(
      SpecialArtifact treeArtifact, String... parentRelativePaths) throws IOException {
    TreeArtifactValue.Builder builder = TreeArtifactValue.newBuilder(treeArtifact);

    for (String parentRelativePath : parentRelativePaths) {
      TreeFileArtifact childArtifact =
          TreeFileArtifact.createTreeOutput(treeArtifact, parentRelativePath);
      createFile(childArtifact.getPath());
      builder.putChild(childArtifact, FileArtifactValue.createForTesting(childArtifact));
    }

    if (includeArchivedTreeArtifacts) {
      ArchivedTreeArtifact archivedArtifact = ArchivedTreeArtifact.createForTree(treeArtifact);
      createFile(archivedArtifact.getPath());
      builder.setArchivedRepresentation(
          archivedArtifact, FileArtifactValue.createForTesting(archivedArtifact));
    }

    return builder.build();
  }

  private DerivedArtifact createFileArtifact(String relativePath, ActionLookupKey owner) {
    return DerivedArtifact.create(
        derivedRoot, DERIVED_PATH_PREFIX.getRelative(relativePath), owner);
  }

  private SpecialArtifact createTreeArtifact(String relativePath, ActionLookupKey owner) {
    SpecialArtifact treeArtifact =
        SpecialArtifact.create(
            derivedRoot,
            DERIVED_PATH_PREFIX.getRelative(relativePath),
            owner,
            SpecialArtifactType.TREE);
    treeArtifact.setGeneratingActionKey(ActionLookupData.create(owner, 0));
    return treeArtifact;
  }

  private static ActionExecutionValue createActionExecutionValue(
      ImmutableMap<Artifact, TreeArtifactValue> treeArtifacts) {
    return createActionExecutionValue(/*fileArtifacts=*/ ImmutableMap.of(), treeArtifacts);
  }

  private static ActionExecutionValue createActionExecutionValue(
      ImmutableMap<Artifact, FileArtifactValue> fileArtifacts,
      ImmutableMap<Artifact, TreeArtifactValue> treeArtifacts) {
    return ActionExecutionValue.create(
        fileArtifacts,
        treeArtifacts,
        /* outputSymlinks= */ ImmutableList.of(),
        /* discoveredModules= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER));
  }

  private static void createFile(Path file) throws IOException {
    FileSystemUtils.writeIsoLatin1(file);
  }
}
