// Copyright 2016 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.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableSet.toImmutableSet;

import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.io.BaseEncoding;
import com.google.devtools.build.lib.actions.ActionInput;
import com.google.devtools.build.lib.actions.ActionInputHelper;
import com.google.devtools.build.lib.actions.Artifact.ArchivedTreeArtifact;
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.FileContentsProxy;
import com.google.devtools.build.lib.actions.FileStateType;
import com.google.devtools.build.lib.actions.HasDigest;
import com.google.devtools.build.lib.actions.cache.MetadataDigestUtils;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.vfs.Dirent;
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 com.google.devtools.build.skyframe.SkyValue;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;

/**
 * Value for TreeArtifacts, which contains a digest and the {@link FileArtifactValue}s of its child
 * {@link TreeFileArtifact}s.
 */
public class TreeArtifactValue implements HasDigest, SkyValue {

  /**
   * Comparator based on exec path which works on {@link ActionInput} as opposed to {@link
   * com.google.devtools.build.lib.actions.Artifact}. This way, we can use an {@link ActionInput} to
   * search {@link #childData}.
   */
  @SerializationConstant @AutoCodec.VisibleForSerialization
  static final Comparator<ActionInput> EXEC_PATH_COMPARATOR =
      (input1, input2) -> input1.getExecPath().compareTo(input2.getExecPath());

  private static final ImmutableSortedMap<TreeFileArtifact, FileArtifactValue> EMPTY_MAP =
      childDataBuilder().buildOrThrow();

  private static ImmutableSortedMap.Builder<TreeFileArtifact, FileArtifactValue>
      childDataBuilder() {
    return new ImmutableSortedMap.Builder<>(EXEC_PATH_COMPARATOR);
  }

  /** Returns an empty {@link TreeArtifactValue}. */
  public static TreeArtifactValue empty() {
    return EMPTY;
  }

  /**
   * Returns a new {@link Builder} for the given parent tree artifact.
   *
   * <p>The returned builder only supports adding children under this parent. To build multiple tree
   * artifacts at once, use {@link MultiBuilder}.
   */
  public static Builder newBuilder(SpecialArtifact parent) {
    return new Builder(parent);
  }

  /** Builder for constructing multiple instances of {@link TreeArtifactValue} at once. */
  public static final class MultiBuilder {

    private final Map<SpecialArtifact, Builder> map = new HashMap<>();

    private MultiBuilder() {}

    /**
     * Puts a child tree file into this builder under its {@linkplain TreeFileArtifact#getParent
     * parent}.
     *
     * @return {@code this} for convenience
     */
    @CanIgnoreReturnValue
    public MultiBuilder putChild(TreeFileArtifact child, FileArtifactValue metadata) {
      map.computeIfAbsent(child.getParent(), Builder::new).putChild(child, metadata);
      return this;
    }

    /**
     * Sets the archived representation and its metadata for the {@linkplain
     * ArchivedTreeArtifact#getParent parent} of the provided tree artifact.
     *
     * <p>Setting an archived representation is only allowed once per {@linkplain SpecialArtifact
     * tree artifact}.
     */
    @CanIgnoreReturnValue
    public MultiBuilder setArchivedRepresentation(
        ArchivedTreeArtifact archivedArtifact, FileArtifactValue metadata) {
      map.computeIfAbsent(archivedArtifact.getParent(), Builder::new)
          .setArchivedRepresentation(ArchivedRepresentation.create(archivedArtifact, metadata));
      return this;
    }

    /**
     * Removes all of collected data for a given tree artifact.
     *
     * <p>No-op if there is no data for a given tree artifact.
     */
    @CanIgnoreReturnValue
    public MultiBuilder remove(SpecialArtifact treeArtifact) {
      checkArgument(treeArtifact.isTreeArtifact(), "Not a tree artifact: %s", treeArtifact);
      map.remove(treeArtifact);
      return this;
    }

    /**
     * For each unique parent seen by this builder, passes the aggregated metadata to {@link
     * TreeArtifactInjector#injectTree}.
     */
    public void injectTo(TreeArtifactInjector treeInjector) {
      map.forEach((parent, builder) -> treeInjector.injectTree(parent, builder.build()));
    }
  }

  /** Returns a new {@link MultiBuilder}. */
  public static MultiBuilder newMultiBuilder() {
    return new MultiBuilder();
  }

  /**
   * Archived representation of a tree artifact which contains a representation of the filesystem
   * tree starting with the tree artifact directory.
   *
   * <p>Contains both the {@linkplain ArchivedTreeArtifact artifact} for the archived file and the
   * metadata for it.
   */
  @AutoValue
  public abstract static class ArchivedRepresentation {
    public abstract ArchivedTreeArtifact archivedTreeFileArtifact();

    public abstract FileArtifactValue archivedFileValue();

    public static ArchivedRepresentation create(
        ArchivedTreeArtifact archivedTreeFileArtifact, FileArtifactValue fileArtifactValue) {
      return new AutoValue_TreeArtifactValue_ArchivedRepresentation(
          archivedTreeFileArtifact, fileArtifactValue);
    }
  }

  @SuppressWarnings("WeakerAccess") // Serialization constant.
  @SerializationConstant
  @AutoCodec.VisibleForSerialization
  static final TreeArtifactValue EMPTY =
      new TreeArtifactValue(
          MetadataDigestUtils.fromMetadata(ImmutableMap.of()),
          EMPTY_MAP,
          0L,
          /*archivedRepresentation=*/ null,
          /*materializationExecPath=*/ null,
          /*entirelyRemote=*/ false);

  private final byte[] digest;
  private final ImmutableSortedMap<TreeFileArtifact, FileArtifactValue> childData;
  private final long totalChildSize;

  /**
   * Optional archived representation of the entire tree artifact which can be sent instead of all
   * the items in the directory.
   */
  @Nullable private final ArchivedRepresentation archivedRepresentation;

  /**
   * Optional materialization path.
   *
   * <p>If present, this artifact is a copy of another artifact. It is still tracked as a
   * non-symlink by Bazel, but materialized in the local filesystem as a symlink to the original
   * artifact, whose contents live at this location. This is used by {@link
   * com.google.devtools.build.lib.remote.AbstractActionInputPrefetcher} to implement zero-cost
   * copies of remotely stored artifacts.
   */
  @Nullable private final PathFragment materializationExecPath;

  private final boolean entirelyRemote;

  /** A FileArtifactValue used to stand in for a TreeArtifactValue. */
  private static final class TreeArtifactCompositeFileArtifactValue extends FileArtifactValue {
    private final byte[] digest;
    private final boolean isRemote;
    @Nullable private final PathFragment materializationExecPath;

    TreeArtifactCompositeFileArtifactValue(
        byte[] digest, boolean isRemote, @Nullable PathFragment materializationExecPath) {
      this.digest = digest;
      this.isRemote = isRemote;
      this.materializationExecPath = materializationExecPath;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (!(o instanceof TreeArtifactCompositeFileArtifactValue)) {
        return false;
      }
      TreeArtifactCompositeFileArtifactValue that = (TreeArtifactCompositeFileArtifactValue) o;
      return Arrays.equals(digest, that.digest)
          && Objects.equals(materializationExecPath, that.materializationExecPath);
    }

    @Override
    public int hashCode() {
      return Objects.hash(Arrays.hashCode(digest), materializationExecPath);
    }

    @Override
    public FileStateType getType() {
      return FileStateType.DIRECTORY;
    }

    @Override
    public byte[] getDigest() {
      return digest;
    }

    @Override
    @Nullable
    public FileContentsProxy getContentsProxy() {
      return null;
    }

    @Override
    public long getSize() {
      return 0;
    }

    @Override
    public boolean wasModifiedSinceDigest(Path path) {
      return false;
    }

    @Override
    public long getModifiedTime() {
      throw new UnsupportedOperationException();
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(this)
          .add("digest", BaseEncoding.base16().lowerCase().encode(digest))
          .add("materializationExecPath", materializationExecPath)
          .toString();
    }

    @Override
    protected boolean couldBeModifiedByMetadata(FileArtifactValue o) {
      return false;
    }

    @Override
    public boolean isRemote() {
      return isRemote;
    }

    @Override
    public Optional<PathFragment> getMaterializationExecPath() {
      return Optional.ofNullable(materializationExecPath);
    }
  }

  private TreeArtifactValue(
      byte[] digest,
      ImmutableSortedMap<TreeFileArtifact, FileArtifactValue> childData,
      long totalChildSize,
      @Nullable ArchivedRepresentation archivedRepresentation,
      @Nullable PathFragment materializationExecPath,
      boolean entirelyRemote) {
    this.digest = digest;
    this.childData = childData;
    this.totalChildSize = totalChildSize;
    this.archivedRepresentation = archivedRepresentation;
    this.materializationExecPath = materializationExecPath;
    this.entirelyRemote = entirelyRemote;
  }

  public FileArtifactValue getMetadata() {
    return new TreeArtifactCompositeFileArtifactValue(
        digest, entirelyRemote, materializationExecPath);
  }

  ImmutableSet<PathFragment> getChildPaths() {
    return childData.keySet().stream()
        .map(TreeFileArtifact::getParentRelativePath)
        .collect(toImmutableSet());
  }

  @Override
  public byte[] getDigest() {
    return digest.clone();
  }

  public ImmutableSet<TreeFileArtifact> getChildren() {
    return childData.keySet();
  }

  public long getTotalChildBytes() {
    return totalChildSize;
  }

  /** Return archived representation of the tree artifact (if present). */
  public Optional<ArchivedRepresentation> getArchivedRepresentation() {
    return Optional.ofNullable(archivedRepresentation);
  }

  /** Return materialization path (if present). */
  public Optional<PathFragment> getMaterializationExecPath() {
    return Optional.ofNullable(materializationExecPath);
  }

  @VisibleForTesting
  @Nullable
  public ArchivedTreeArtifact getArchivedArtifactForTesting() {
    return archivedRepresentation != null
        ? archivedRepresentation.archivedTreeFileArtifact()
        : null;
  }

  public ImmutableSortedMap<TreeFileArtifact, FileArtifactValue> getChildValues() {
    return childData;
  }

  /** Returns an entry for child with given exec path or null if no such child is present. */
  @SuppressWarnings("unchecked")
  @Nullable
  public Map.Entry<TreeFileArtifact, FileArtifactValue> findChildEntryByExecPath(
      PathFragment execPath) {
    ActionInput searchToken = ActionInputHelper.fromPath(execPath);
    // Not really a copy -- original map is already an ImmutableSortedMap using the same comparator.
    ImmutableSortedMap<ActionInput, FileArtifactValue> casted =
        ImmutableSortedMap.copyOf(childData, EXEC_PATH_COMPARATOR);
    checkState(casted == (Object) childData, "Casting children resulted with a copy");
    Map.Entry<? extends ActionInput, FileArtifactValue> entry = casted.floorEntry(searchToken);
    return entry != null && entry.getKey().getExecPath().equals(execPath)
        ? (Map.Entry<TreeFileArtifact, FileArtifactValue>) entry
        : null;
  }

  /** Returns true if the {@link TreeFileArtifact}s are only stored remotely. */
  public boolean isEntirelyRemote() {
    return entirelyRemote;
  }

  @Override
  public int hashCode() {
    return Arrays.hashCode(digest);
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }

    if (!(other instanceof TreeArtifactValue)) {
      return false;
    }

    TreeArtifactValue that = (TreeArtifactValue) other;
    if (!Arrays.equals(digest, that.digest)) {
      return false;
    }

    return childData.equals(that.childData);
  }

  @Override
  public String toString() {
    return MoreObjects.toStringHelper(this)
        .add("digest", digest)
        .add("childData", childData)
        .add("archivedRepresentation", archivedRepresentation)
        .add("materializationExecPath", materializationExecPath)
        .toString();
  }

  /**
   * Represents a tree artifact that was intentionally omitted, similar to {@link
   * FileArtifactValue#OMITTED_FILE_MARKER}.
   */
  @SerializationConstant
  public static final TreeArtifactValue OMITTED_TREE_MARKER = createMarker("OMITTED_TREE_MARKER");

  /**
   * A TreeArtifactValue that represents a missing TreeArtifact. This is occasionally useful because
   * Java's concurrent collections disallow null members.
   */
  public static final TreeArtifactValue MISSING_TREE_ARTIFACT =
      createMarker("MISSING_TREE_ARTIFACT");

  private static TreeArtifactValue createMarker(String toStringRepresentation) {
    return new TreeArtifactValue(
        null,
        EMPTY_MAP,
        0L,
        /*archivedRepresentation=*/ null,
        /*materializationExecPath=*/ null,
        /*entirelyRemote=*/ false) {
      @Override
      public ImmutableSet<TreeFileArtifact> getChildren() {
        throw new UnsupportedOperationException(toString());
      }

      @Override
      public ImmutableSortedMap<TreeFileArtifact, FileArtifactValue> getChildValues() {
        throw new UnsupportedOperationException(toString());
      }

      @Override
      public FileArtifactValue getMetadata() {
        throw new UnsupportedOperationException(toString());
      }

      @Override
      ImmutableSet<PathFragment> getChildPaths() {
        throw new UnsupportedOperationException(toString());
      }

      @Nullable
      @Override
      public byte[] getDigest() {
        throw new UnsupportedOperationException(toString());
      }

      @Override
      public int hashCode() {
        return System.identityHashCode(this);
      }

      @Override
      public boolean equals(Object other) {
        return this == other;
      }

      @Override
      public String toString() {
        return toStringRepresentation;
      }
    };
  }

  /** Visitor for use in {@link #visitTree}. */
  @FunctionalInterface
  public interface TreeArtifactVisitor {
    /**
     * Called for every directory entry encountered during tree traversal.
     *
     * <p>Symlinks are not followed during traversal and are simply reported as {@link
     * Dirent.Type#SYMLINK} regardless of whether they point to a file, directory, or are dangling.
     *
     * <p>{@code type} is guaranteed never to be {@link Dirent.Type#UNKNOWN}, since if this type is
     * encountered, {@link IOException} is immediately thrown without invoking the visitor.
     *
     * <p>If the implementation throws {@link IOException}, traversal is immediately halted and the
     * exception is propagated.
     */
    void visit(PathFragment parentRelativePath, Dirent.Type type) throws IOException;
  }

  /**
   * Recursively visits all descendants under a directory.
   *
   * <p>{@link TreeArtifactVisitor#visit} is invoked on {@code visitor} for each directory, file,
   * and symlink under the given {@code parentDir}.
   *
   * <p>This method is intended to provide uniform semantics for constructing a tree artifact,
   * including special logic that validates directory entries. Invalid directory entries include a
   * symlink that traverses outside of the tree artifact and any entry of {@link
   * Dirent.Type#UNKNOWN}, such as a named pipe.
   *
   * @throws IOException if there is any problem reading or validating outputs under the given tree
   *     artifact directory, or if {@link TreeArtifactVisitor#visit} throws {@link IOException}
   */
  public static void visitTree(Path parentDir, TreeArtifactVisitor visitor)
      throws IOException, InterruptedException {
    visitTree(parentDir, PathFragment.EMPTY_FRAGMENT, checkNotNull(visitor));
  }

  private static void visitTree(Path parentDir, PathFragment subdir, TreeArtifactVisitor visitor)
      throws IOException {
    for (Dirent dirent : parentDir.getRelative(subdir).readdir(Symlinks.NOFOLLOW)) {
      PathFragment parentRelativePath = subdir.getChild(dirent.getName());
      Dirent.Type type = dirent.getType();

      if (type == Dirent.Type.UNKNOWN) {
        throw new IOException(
            "Could not determine type of file for " + parentRelativePath + " under " + parentDir);
      }

      if (type == Dirent.Type.SYMLINK) {
        checkSymlink(subdir, parentDir.getRelative(parentRelativePath));
      }

      visitor.visit(parentRelativePath, type);

      if (type == Dirent.Type.DIRECTORY) {
        visitTree(parentDir, parentRelativePath, visitor);
      }
    }
  }

  private static void checkSymlink(PathFragment subDir, Path path) throws IOException {
    PathFragment linkTarget = path.readSymbolicLinkUnchecked();
    if (linkTarget.isAbsolute()) {
      // We tolerate absolute symlinks here. They will probably be dangling if any downstream
      // consumer tries to read them, but let that be downstream's problem.
      return;
    }

    // Visit each path segment of the link target to catch any path traversal outside of the
    // TreeArtifact root directory. For example, for TreeArtifact a/b/c, it is possible to have a
    // symlink, a/b/c/sym_link that points to ../outside_dir/../c/link_target. Although this symlink
    // points to a file under the TreeArtifact, the link target traverses outside of the
    // TreeArtifact into a/b/outside_dir.
    PathFragment intermediatePath = subDir;
    for (String pathSegment : linkTarget.segments()) {
      intermediatePath = intermediatePath.getRelative(pathSegment);
      if (intermediatePath.containsUplevelReferences()) {
        String errorMessage =
            String.format(
                "A TreeArtifact may not contain relative symlinks whose target paths traverse "
                    + "outside of the TreeArtifact, found %s pointing to %s.",
                path, linkTarget);
        throw new IOException(errorMessage);
      }
    }
  }

  /** Builder for a {@link TreeArtifactValue}. */
  public static final class Builder {
    private final ImmutableSortedMap.Builder<TreeFileArtifact, FileArtifactValue> childData =
        childDataBuilder();
    private ArchivedRepresentation archivedRepresentation;
    private PathFragment materializationExecPath;
    private final SpecialArtifact parent;

    Builder(SpecialArtifact parent) {
      checkArgument(parent.isTreeArtifact(), "%s is not a tree artifact", parent);
      this.parent = parent;
    }

    /**
     * Adds a child to this builder.
     *
     * <p>The child's {@linkplain TreeFileArtifact#getParent parent} <em>must</em> match the parent
     * with which this builder was initialized.
     *
     * <p>Children may be added in any order. The children are sorted prior to constructing the
     * final {@link TreeArtifactValue}.
     *
     * <p>It is illegal to call this method with {@link FileArtifactValue#OMITTED_FILE_MARKER}. When
     *
     * <p>It is illegal to call this method with {@link FileArtifactValue#OMITTED_FILE_MARKER}. When
     * children are omitted, use {@link TreeArtifactValue#OMITTED_TREE_MARKER}.
     *
     * @return {@code this} for convenience
     */
    @CanIgnoreReturnValue
    public Builder putChild(TreeFileArtifact child, FileArtifactValue metadata) {
      checkArgument(
          child.getParent().equals(parent),
          "While building TreeArtifactValue for %s, got %s with parent %s",
          parent,
          child,
          child.getParent());
      checkArgument(
          !FileArtifactValue.OMITTED_FILE_MARKER.equals(metadata),
          "Cannot construct TreeArtifactValue for %s because child %s was omitted",
          parent,
          child);
      childData.put(child, metadata);
      return this;
    }

    public Builder setArchivedRepresentation(
        ArchivedTreeArtifact archivedTreeArtifact, FileArtifactValue metadata) {
      return setArchivedRepresentation(
          ArchivedRepresentation.create(archivedTreeArtifact, metadata));
    }

    @CanIgnoreReturnValue
    public Builder setArchivedRepresentation(ArchivedRepresentation archivedRepresentation) {
      checkState(
          this.archivedRepresentation == null,
          "Tried to add 2 archived representations for: %s",
          parent);
      checkArgument(
          parent.equals(archivedRepresentation.archivedTreeFileArtifact().getParent()),
          "Cannot add archived representation: %s for a mismatching tree artifact: %s",
          archivedRepresentation,
          parent);
      checkArgument(
          !archivedRepresentation.archivedFileValue().equals(FileArtifactValue.OMITTED_FILE_MARKER),
          "Cannot add archived representation: %s to %s because it has omitted metadata.",
          archivedRepresentation,
          parent);
      this.archivedRepresentation = archivedRepresentation;
      return this;
    }

    @CanIgnoreReturnValue
    public Builder setMaterializationExecPath(PathFragment materializationExecPath) {
      checkState(
          this.materializationExecPath == null,
          "Tried to set materialization exec path multiple times for: %s",
          parent);
      this.materializationExecPath = materializationExecPath;
      return this;
    }

    /** Builds the final {@link TreeArtifactValue}. */
    public TreeArtifactValue build() {
      ImmutableSortedMap<TreeFileArtifact, FileArtifactValue> finalChildData =
          childData.buildOrThrow();
      if (finalChildData.isEmpty()
          && archivedRepresentation == null
          && materializationExecPath == null) {
        return EMPTY;
      }

      Fingerprint fingerprint = new Fingerprint();
      boolean entirelyRemote =
          archivedRepresentation == null || archivedRepresentation.archivedFileValue().isRemote();

      long totalChildSize = 0;
      for (Map.Entry<TreeFileArtifact, FileArtifactValue> childData : finalChildData.entrySet()) {
        // Digest will be deterministic because children are sorted.
        fingerprint.addPath(childData.getKey().getParentRelativePath());
        FileArtifactValue metadata = childData.getValue();
        metadata.addTo(fingerprint);

        // Tolerate a mix of local and remote children (b/152496153#comment80).
        entirelyRemote &= metadata.isRemote();

        if (metadata.getType() == FileStateType.REGULAR_FILE) {
          totalChildSize += metadata.getSize();
        }
      }

      if (archivedRepresentation != null) {
        archivedRepresentation.archivedFileValue().addTo(fingerprint);
      }

      return new TreeArtifactValue(
          fingerprint.digestAndReset(),
          finalChildData,
          totalChildSize,
          archivedRepresentation,
          materializationExecPath,
          entirelyRemote);
    }
  }
}
