// Copyright 2014 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.actions;

import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

/** Helper utility to create ActionInput instances. */
public final class ActionInputHelper {
  private ActionInputHelper() {}

  /**
   * Most ActionInputs are created and never used again. On the off chance that one is, however, we
   * implement equality via path comparison. Since file caches are keyed by ActionInput, equality
   * checking does come up.
   */
  public abstract static class BasicActionInput implements ActionInput {

    // TODO(lberki): Plumb this flag from InputTree.build() somehow.
    @Override
    public boolean isSymlink() {
      return false;
    }

    @Override
    public boolean isDirectory() {
      return false;
    }

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

    @Override
    public boolean equals(Object other) {
      if (this == other) {
        return true;
      }
      if (!(other instanceof BasicActionInput)) {
        return false;
      }
      return getExecPathString().equals(((BasicActionInput) other).getExecPathString());
    }

    @Override
    public String toString() {
      return "BasicActionInput: " + getExecPathString();
    }
  }

  /**
   * Creates an ActionInput with just the given relative path and no digest.
   *
   * @param path the relative path of the input.
   * @return a ActionInput.
   */
  public static ActionInput fromPath(String path) {
    return new BasicActionInput() {
      @Override
      public String getExecPathString() {
        return path;
      }

      @Override
      public PathFragment getExecPath() {
        return PathFragment.create(path);
      }
    };
  }

  /**
   * Creates an ActionInput with just the given relative path and no digest.
   *
   * @param path the relative path of the input.
   * @return a ActionInput.
   */
  public static ActionInput fromPath(PathFragment path) {
    return new BasicActionInput() {
      @Override
      public String getExecPathString() {
        return path.getPathString();
      }

      @Override
      public PathFragment getExecPath() {
        return path;
      }
    };
  }

  /**
   * Expands middleman and tree artifacts in a sequence of {@link ActionInput}s.
   *
   * <p>If {@code keepEmptyTreeArtifacts} is true, a tree artifact will be included in the
   * constructed list when it expands into zero file artifacts. Otherwise, only the file artifacts
   * the tree artifact expands into will be included.
   *
   * <p>Middleman artifacts will be returned if {@code keepMiddlemanArtifacts} is set.
   *
   * <p>Non-middleman, non-tree artifacts are returned untouched.
   */
  public static List<ActionInput> expandArtifacts(
      NestedSet<? extends ActionInput> inputs,
      ArtifactExpander artifactExpander,
      boolean keepEmptyTreeArtifacts,
      boolean keepMiddlemanArtifacts) {
    List<ActionInput> result = new ArrayList<>();
    Set<Artifact> emptyTreeArtifacts = new TreeSet<>();
    Set<Artifact> treeFileArtifactParents = new HashSet<>();
    for (ActionInput input : inputs.toList()) {
      if (input instanceof Artifact) {
        Artifact inputArtifact = (Artifact) input;
        Artifact.addExpandedArtifact(
            inputArtifact, result, artifactExpander, emptyTreeArtifacts, keepMiddlemanArtifacts);
        if (inputArtifact.isChildOfDeclaredDirectory()) {
          treeFileArtifactParents.add(inputArtifact.getParent());
        }
      } else {
        result.add(input);
      }
    }

    if (keepEmptyTreeArtifacts) {
      emptyTreeArtifacts.removeAll(treeFileArtifactParents);
      result.addAll(emptyTreeArtifacts);
    }
    return result;
  }

  public static Iterable<String> toExecPaths(Iterable<? extends ActionInput> artifacts) {
    return Iterables.transform(artifacts, ActionInput::getExecPathString);
  }

  /** Returns the {@link Path} for an {@link ActionInput}. */
  public static Path toInputPath(ActionInput input, Path execRoot) {
    Preconditions.checkNotNull(input, "input");
    Preconditions.checkNotNull(execRoot, "execRoot");

    return (input instanceof Artifact)
        ? ((Artifact) input).getPath()
        : execRoot.getRelative(input.getExecPath());
  }
}
