package org.checkerframework.checker.calledmethods;

import java.util.LinkedHashSet;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.common.accumulation.AccumulationChecker;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.common.returnsreceiver.ReturnsReceiverChecker;
import org.checkerframework.common.value.ValueChecker;
import org.checkerframework.framework.qual.StubFiles;
import org.checkerframework.framework.source.SupportedOptions;
import org.checkerframework.framework.source.SuppressWarningsPrefix;

/**
 * The Called Methods Checker tracks the methods that have definitely been called on an object. One
 * common use case for the Called Methods Checker is to specify safe combinations of options to
 * builder or builder-like interfaces, preventing objects from being instantiated incompletely.
 */
@SuppressWarningsPrefix({
  // Preferred checkername.
  "calledmethods",
  // Deprecated checkernames, supported for backward compatibility.
  "builder",
  "object.construction",
  "objectconstruction"
})
@SupportedOptions({
  CalledMethodsChecker.USE_VALUE_CHECKER,
  CalledMethodsChecker.COUNT_FRAMEWORK_BUILD_CALLS,
  CalledMethodsChecker.DISABLE_BUILDER_FRAMEWORK_SUPPORTS,
  CalledMethodsChecker.DISABLE_RETURNS_RECEIVER
})
@StubFiles({"DescribeImages.astub", "GenerateDataKey.astub"})
public class CalledMethodsChecker extends AccumulationChecker {

  /**
   * If this option is supplied, count the number of analyzed calls to build() in supported builder
   * frameworks and print it when analysis is complete. Useful for collecting metrics.
   */
  public static final String COUNT_FRAMEWORK_BUILD_CALLS = "countFrameworkBuildCalls";

  /**
   * This option disables the support for (and therefore the automated checking of) code that uses
   * the given builder frameworks. Useful when a user **only** wants to enforce specifications on
   * custom builder objects (such as the AWS SDK examples).
   */
  public static final String DISABLE_BUILDER_FRAMEWORK_SUPPORTS = "disableBuilderFrameworkSupports";

  /**
   * If this option is supplied, use the Value Checker to reduce false positives when analyzing
   * calls to the AWS SDK.
   */
  public static final String USE_VALUE_CHECKER = "useValueChecker";

  /**
   * Some use cases for the Called Methods Checker do not involve checking fluent APIs, and in those
   * cases disabling the Returns Receiver Checker using this flag will make the Called Methods
   * Checker run much faster.
   */
  public static final String DISABLE_RETURNS_RECEIVER = "disableReturnsReceiver";

  /**
   * The number of calls to build frameworks supported by this invocation. Incremented only if the
   * {@link #COUNT_FRAMEWORK_BUILD_CALLS} option was supplied.
   */
  int numBuildCalls = 0;

  /** Never access this boolean directly. Call {@link #isReturnsReceiverDisabled()} instead. */
  private @MonotonicNonNull Boolean returnsReceiverDisabled = null;

  /**
   * Was the Returns Receiver Checker disabled on the command line?
   *
   * @return whether the -AdisableReturnsReceiver option was specified on the command line
   */
  private boolean isReturnsReceiverDisabled() {
    if (returnsReceiverDisabled == null) {
      returnsReceiverDisabled = hasOptionNoSubcheckers(DISABLE_RETURNS_RECEIVER);
    }
    return returnsReceiverDisabled;
  }

  @Override
  protected LinkedHashSet<Class<? extends BaseTypeChecker>> getImmediateSubcheckerClasses() {
    LinkedHashSet<Class<? extends BaseTypeChecker>> checkers =
        super.getImmediateSubcheckerClasses();
    if (!isReturnsReceiverDisabled()) {
      checkers.add(ReturnsReceiverChecker.class);
    }
    // BaseTypeChecker#hasOption calls this method (so that all subcheckers' options are
    // considered), so the processingEnvironment must be checked for options directly.
    if (this.processingEnv.getOptions().containsKey(USE_VALUE_CHECKER)
        || this.processingEnv
            .getOptions()
            .containsKey(this.getClass().getSimpleName() + "_" + USE_VALUE_CHECKER)) {
      checkers.add(ValueChecker.class);
    }
    return checkers;
  }

  /**
   * Check whether the given alias analysis is enabled by this particular accumulation checker.
   *
   * @param aliasAnalysis the analysis to check
   * @return true iff the analysis is enabled
   */
  @Override
  public boolean isEnabled(AliasAnalysis aliasAnalysis) {
    if (aliasAnalysis == AliasAnalysis.RETURNS_RECEIVER) {
      return !isReturnsReceiverDisabled();
    }
    return super.isEnabled(aliasAnalysis);
  }

  @Override
  public void typeProcessingOver() {
    if (getBooleanOption(COUNT_FRAMEWORK_BUILD_CALLS)) {
      System.out.printf("Found %d build() method calls.%n", numBuildCalls);
    }
    super.typeProcessingOver();
  }
}
