// 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.ActionAnalysisMetadata.MiddlemanType;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Iterator;
import javax.annotation.Nullable;

/**
 * A factory to create middleman objects.
 */
@ThreadSafe
public final class MiddlemanFactory {

  private final ArtifactFactory artifactFactory;
  private final ActionRegistry actionRegistry;

  public MiddlemanFactory(
      ArtifactFactory artifactFactory, ActionRegistry actionRegistry) {
    this.artifactFactory = Preconditions.checkNotNull(artifactFactory);
    this.actionRegistry = Preconditions.checkNotNull(actionRegistry);
  }

  /**
   * Creates a {@link MiddlemanType#AGGREGATING_MIDDLEMAN aggregating} middleman.
   *
   * @param owner the owner of the action that will be created; must not be null
   * @param purpose the purpose for which this middleman is created. This should be a string which
   *        is suitable for use as a filename. A single rule may have many middlemen with distinct
   *        purposes.
   * @param inputs the set of artifacts for which the created artifact is to be the middleman.
   * @param middlemanDir the directory in which to place the middleman.
   * @return null iff {@code inputs} is empty; the single element of {@code inputs} if there's only
   *         one; a new aggregating middleman for the {@code inputs} otherwise
   */
  public Artifact createAggregatingMiddleman(
      ActionOwner owner, String purpose, Iterable<Artifact> inputs, Root middlemanDir) {
    if (hasExactlyOneInput(inputs)) { // Optimization: No middleman for just one input.
      return Iterables.getOnlyElement(inputs);
    }
    Pair<Artifact, Action> result = createMiddleman(
        owner, Label.print(owner.getLabel()), purpose, inputs, middlemanDir,
        MiddlemanType.AGGREGATING_MIDDLEMAN);
    return result == null ? null : result.getFirst();
  }

  /**
   * Returns <code>null</code> iff inputs is empty. Returns the sole element
   * of inputs iff <code>inputs.size()==1</code>. Otherwise, returns a
   * middleman artifact and creates a middleman action that generates that
   * artifact.
   *
   * @param owner the owner of the action that will be created.
   * @param owningArtifact the artifact of the file for which the runfiles
   *        should be created. There may be at most one set of runfiles for
   *        an owning artifact, unless the owning artifact is null. There
   *        may be at most one set of runfiles per owner with a null
   *        owning artifact.
   *        Further, if the owning Artifact is non-null, the owning Artifacts'
   *        root-relative path must be unique and the artifact must be part
   *        of the runfiles tree for which this middleman is created. Usually
   *        this artifact will be an executable program.
   * @param inputs the set of artifacts for which the created artifact is to be
   *        the middleman.
   * @param middlemanDir the directory in which to place the middleman.
   */
  public Artifact createRunfilesMiddleman(
      ActionOwner owner, @Nullable Artifact owningArtifact, Iterable<Artifact> inputs,
      Root middlemanDir, String tag) {
    Preconditions.checkArgument(middlemanDir.isMiddlemanRoot());
    if (hasExactlyOneInput(inputs)) { // Optimization: No middleman for just one input.
      return Iterables.getOnlyElement(inputs);
    }
    String middlemanPath = owningArtifact == null
       ? Label.print(owner.getLabel())
       : owningArtifact.getRootRelativePath().getPathString();
    return createMiddleman(owner, middlemanPath, tag, inputs, middlemanDir,
        MiddlemanType.RUNFILES_MIDDLEMAN).getFirst();
  }

  private <T> boolean hasExactlyOneInput(Iterable<T> iterable) {
    Iterator<T> it = iterable.iterator();
    if (!it.hasNext()) {
      return false;
    }
    it.next();
    return !it.hasNext();
  }

  /**
   * Creates a {@link MiddlemanType#ERROR_PROPAGATING_MIDDLEMAN error-propagating} middleman.
   *
   * @param owner the owner of the action that will be created. May not be null.
   * @param middlemanName a unique file name for the middleman artifact in the {@code middlemanDir};
   *        in practice this is usually the owning rule's label (so it gets escaped as such)
   * @param purpose the purpose for which this middleman is created. This should be a string which
   *        is suitable for use as a filename. A single rule may have many middlemen with distinct
   *        purposes.
   * @param inputs the set of artifacts for which the created artifact is to be the middleman; must
   *        not be null or empty
   * @param middlemanDir the directory in which to place the middleman.
   * @return a middleman that enforces scheduling order (just like a scheduling middleman) and
   *         propagates errors, but is ignored by the dependency checker
   * @throws IllegalArgumentException if {@code inputs} is null or empty
   */
  public Artifact createErrorPropagatingMiddleman(ActionOwner owner, String middlemanName,
      String purpose, Iterable<Artifact> inputs, Root middlemanDir) {
    Preconditions.checkArgument(inputs != null);
    Preconditions.checkArgument(!Iterables.isEmpty(inputs));
    // We must always create this middleman even if there is only one input.
    return createMiddleman(owner, middlemanName, purpose, inputs, middlemanDir,
        MiddlemanType.ERROR_PROPAGATING_MIDDLEMAN).getFirst();
  }

  /**
   * Returns the same artifact as {@code createErrorPropagatingMiddleman} would return,
   * but doesn't create any action.
   */
  public Artifact getErrorPropagatingMiddlemanArtifact(String middlemanName, String purpose,
      Root middlemanDir) {
    return getStampFileArtifact(middlemanName, purpose, middlemanDir);
  }

  /**
   * Creates both normal and scheduling middlemen.
   *
   * <p>Note: there's no need to synchronize this method; the only use of a field is via a call to
   * another synchronized method (getArtifact()).
   *
   * @return null iff {@code inputs} is null or empty; the middleman file and the middleman action
   *         otherwise
   */
  private Pair<Artifact, Action> createMiddleman(
      ActionOwner owner, String middlemanName, String purpose, Iterable<Artifact> inputs,
      Root middlemanDir, MiddlemanType middlemanType) {
    if (inputs == null || Iterables.isEmpty(inputs)) {
      return null;
    }

    Artifact stampFile = getStampFileArtifact(middlemanName, purpose, middlemanDir);
    Action action = new MiddlemanAction(owner, inputs, stampFile, purpose, middlemanType);
    actionRegistry.registerAction(action);
    return Pair.of(stampFile, action);
  }

  /**
   * Creates a normal middleman.
   *
   * <p>If called multiple times, it always returns the same object depending on the {@code
   * purpose}. It does not check that the list of inputs is identical. In contrast to other
   * middleman methods, this one also returns an object if the list of inputs is empty.
   *
   * <p>Note: there's no need to synchronize this method; the only use of a field is via a call to
   * another synchronized method (getArtifact()).
   */
  public Artifact createMiddlemanAllowMultiple(ActionRegistry registry, ActionOwner owner,
      PathFragment packageDirectory, String purpose, Iterable<Artifact> inputs, Root middlemanDir) {
    String escapedPackageDirectory = Actions.escapedPath(packageDirectory.getPathString());
    PathFragment stampName =
        PathFragment.create("_middlemen/" + (purpose.startsWith(escapedPackageDirectory)
                             ? purpose : (escapedPackageDirectory + purpose)));
    Artifact stampFile = artifactFactory.getDerivedArtifact(stampName, middlemanDir,
        actionRegistry.getOwner());
    MiddlemanAction.create(
        registry, owner, inputs, stampFile, purpose, MiddlemanType.AGGREGATING_MIDDLEMAN);
    return stampFile;
  }

  private Artifact getStampFileArtifact(String middlemanName, String purpose, Root middlemanDir) {
    String escapedFilename = Actions.escapedPath(middlemanName);
    PathFragment stampName = PathFragment.create("_middlemen/" + escapedFilename + "-" + purpose);
    Artifact stampFile = artifactFactory.getDerivedArtifact(stampName, middlemanDir,
        actionRegistry.getOwner());
    return stampFile;
  }
}
