// 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.skyframe;

import com.google.devtools.build.lib.concurrent.ThreadSafety;
import com.google.devtools.build.skyframe.NodeEntry.DirtyType;
import java.util.function.Supplier;
import javax.annotation.Nullable;

/** Receiver for various stages of the lifetime of a skyframe node evaluation. */
@ThreadSafety.ThreadSafe
public interface EvaluationProgressReceiver {

  /** A no-op {@link EvaluationProgressReceiver}. */
  EvaluationProgressReceiver NULL = new EvaluationProgressReceiver() {};

  /** New state of the value entry after evaluation. */
  enum EvaluationState {
    /** The value was successfully re-evaluated. */
    BUILT,
    /** The value is clean or re-validated. */
    CLEAN,
  }

  /** Whether or not evaluation of this node succeeded. */
  enum EvaluationSuccessState {
    SUCCESS(true),
    FAILURE(false);

    EvaluationSuccessState(boolean succeeded) {
      this.succeeded = succeeded;
    }

    private final boolean succeeded;

    public boolean succeeded() {
      return succeeded;
    }

    public Supplier<EvaluationSuccessState> supplier() {
      return () -> this;
    }
  }

  /** Overall state of the node while it is being evaluated. */
  enum NodeState {
    /** The node is undergoing a dirtiness check and may be re-validated. */
    CHECK_DIRTY,
    /** The node is prepping for evaluation. */
    INITIALIZING_ENVIRONMENT,
    /** The node is in compute(). */
    COMPUTE,
    /** The node is done evaluation and committing the result. */
    COMMIT,
  }

  /**
   * Notifies that the node for {@code skyKey} has been {@linkplain NodeEntry#markDirty marked
   * dirty} with the given {@link DirtyType}.
   *
   * <p>May be called concurrently from multiple threads.
   *
   * <p>Only called after a successful {@link NodeEntry#markDirty} call: a call that returns a
   * non-null value.
   */
  default void dirtied(SkyKey skyKey, DirtyType dirtyType) {}

  /** Notifies that the node for {@code skyKey} was deleted. */
  default void deleted(SkyKey skyKey) {}

  /**
   * Notifies that {@code skyKey} is about to get queued for evaluation.
   *
   * <p>Note that we don't guarantee that it actually got enqueued or will, only that if everything
   * "goes well" (e.g. no interrupts happen) it will.
   *
   * <p>This guarantee is intentionally vague to encourage writing robust implementations.
   */
  default void enqueueing(SkyKey skyKey) {}

  /**
   * Notifies that the node for {@code skyKey} is about to enter the given {@code nodeState}.
   *
   * <p>Notably, this includes {@link SkyFunction#compute} calls due to Skyframe restarts, but also
   * dirtiness checking and node completion.
   */
  default void stateStarting(SkyKey skyKey, NodeState nodeState) {}

  /**
   * Notifies that the node for {@code skyKey} is about to complete the given {@code nodeState}.
   *
   * <p>Always called symmetrically with {@link #stateStarting(SkyKey, NodeState)}}.
   */
  default void stateEnding(SkyKey skyKey, NodeState nodeState) {}

  /**
   * Notifies that the node for {@code skyKey} has been evaluated, or found to not need
   * re-evaluation.
   *
   * @param newValue The new value. Only available if just evaluated, i.e. on success *and* {@code
   *     state == EvaluationState.BUILT}
   * @param newError The new error. Only available if just evaluated, i.e. on error *and* {@code
   *     state == EvaluationState.BUILT}
   * @param evaluationSuccessState whether the node has a value or only an error, behind a {@link
   *     Supplier} for lazy retrieval. Available regardless of whether the node was just evaluated
   * @param state {@code EvaluationState.BUILT} if the node needed to be evaluated and has a new
   *     value or error (i.e., {@code EvaluationState.BUILT} if and only if at least one of newValue
   *     and newError is non-null)
   * @param directDeps Direct dependencies of {@code skyKey}. This is not-{@code null} when node was
   *     just built, so direct deps are available; {@code null} when node was dirty but marked clean
   *     or was already up-to-date from a prior evaluation.
   */
  default void evaluated(
      SkyKey skyKey,
      @Nullable SkyValue newValue,
      @Nullable ErrorInfo newError,
      Supplier<EvaluationSuccessState> evaluationSuccessState,
      EvaluationState state,
      @Nullable GroupedDeps directDeps) {}
}
