/*
 * 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 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();
}
