/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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.facebook.buck.rules;

import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetPattern;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.util.concurrent.ListenableFuture;

import java.io.File;
import java.io.IOException;

import javax.annotation.Nullable;

public interface BuildRule extends Comparable<BuildRule> {

  public static final String VISIBILITY_PUBLIC = "PUBLIC";

  public BuildTarget getBuildTarget();

  public String getFullyQualifiedName();

  public BuildRuleType getType();

  /**
   * @return the value of the "deps" attribute for this build rule
   */
  public ImmutableSortedSet<BuildRule> getDeps();

  /**
   * @return the value of the "visibility" attribute for this build rule
   */
  public ImmutableSet<BuildTargetPattern> getVisibilityPatterns();

  /**
   * @return whether this build rule is visible to the build target or not
   */
  public boolean isVisibleTo(BuildTarget target);

  /**
   * @return the inputs needed to build this build rule
   */
  public Iterable<InputRule> getInputs();

  /**
   * This method must be idempotent.
   */
  public ListenableFuture<BuildRuleSuccess> build(BuildContext context);

  /**
   * A rule is considered "cached" if it satisfies all of the following criteria:
   * <ol>
   *   <li>the output file for this rule exists
   *   <li>all of the dependencies for this rule are cached
   *   <li>the output file was created using precisely the same dependencies, which in turn have
   *       precisely the same state as when the output file was created
   * </ol>
   * A rule that is cached should not be rebuilt.
   * <p>
   * Note that it is always safe for this method to return {@code false}; however, that may result
   * in unnecessary rebuilding.
   */
  public boolean isCached(BuildContext context) throws IOException;

  /**
   * A rule is considered to have uncached descendants if it satisfies any of the following
   * criteria:
   * <ol>
   *   <li>this rule is uncached as determined by {@link BuildRule#isCached(BuildContext)}
   *   <li>any of the dependencies for this rule have uncached descendants.
   * </ol>
   * Some build rules only need to be rebuilt if some subset of their dependencies are uncached vs.
   * if any of their descendants are uncached.  Other rules (like packaging rules) need to run if
   * any of their descendants are uncached.
   * <p>
   * Note that it is always safe for this method to return {@code true}; however, that may result
   * in unnecessary rebuilding.
   */
  public boolean hasUncachedDescendants(BuildContext context) throws IOException;

  /**
   * @return whether this rule exists only in an Android project.
   */
  public boolean isAndroidRule();

  public boolean isLibrary();

  /**
   * @return whether or not this rule is considered a packaging rule.  Packaging rules
   *   (like java_binary) are rules that package up all of their transitive dependencies in their
   *   final output.
   */
  public boolean isPackagingRule();

  /**
   * @return whether or not this rule exports its dependencies to all rules depending on it.
   */
  public boolean getExportDeps();

  /**
   * Return the primary output of the build rule. This must be a single file, or null if there is
   * no output.
   *
   * @return the output file generated by this rule, if there is one.
   */
  @Nullable
  public File getOutput();

  /**
   * If the BuildRule has an output (as reported by getOutput()), return the OutputKey associated
   * with the file returned by getOutput(); return a non-idempotent OutputKey otherwise.
   *
   * @return key based on the BuildRule's output contents if getOutput() returns non-null; a
   * nonIdempotent OutputKey otherwise. A missing/unreadable output file results in a non-idempotent
   * OutputKey.
   */
  public OutputKey getOutputKey();

  /**
   * If the resulting RuleKey is non-idempotent, it must not be internally memoized -- subsequent
   * calls to getRuleKey() must re-evaluate the BuildRule's transitive state. Under normal operating
   * conditions non-idempotent RuleKeys may arise due to not-yet-generated outputs. With careful
   * ordering of execution planning versus RuleKey generation it is usually possible to avoid the
   * creation of non-idempotent RuleKeys. However, dependency graph construction/evaluation would
   * need to be incremental in order to reliably maintain an invariant which would allow blind
   * RuleKey memoization.
   *
   * @return key based on the BuildRule's state, including the transitive closure of its
   * dependencies' keys.
   */
  public RuleKey getRuleKey();

  /** @return the same value as {@link #getFullyQualifiedName()} */
  @Override
  public String toString();
}
