// 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.query2.query;

import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.NoSuchThingException;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.pkgcache.TargetEdgeObserver;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.util.DetailedExitCode;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;

/**
 * Record errors, such as missing package/target or rules containing errors, encountered during
 * visitation. Emit an error message upon encountering missing edges
 *
 * <p>The accessor {@link #hasErrors}) may not be called until the concurrent phase is over, i.e.
 * all external calls to visit() methods have completed.
 *
 * <p>If you need to report errors to the console during visitation, use the subclass {@link
 * ErrorPrintingTargetEdgeErrorObserver}.
 */
class TargetEdgeErrorObserver implements TargetEdgeObserver {

  /**
   * True iff errors were encountered. Note, may be set to "true" during the concurrent phase.
   * Volatile, because it is assigned by worker threads and read by the main thread without monitor
   * synchronization.
   */
  private volatile boolean hasErrors = false;

  private final AtomicReference<DetailedExitCode> errorCode = new AtomicReference<>();

  /**
   * Reports an unresolved label error and records the fact that an error was encountered.
   *
   * @param target the target that referenced the unresolved label
   * @param label the label that could not be resolved
   * @param e the exception that was thrown when the label could not be resolved
   */
  @ThreadSafety.ThreadSafe
  @Override
  public void missingEdge(Target target, Label label, NoSuchThingException e) {
    hasErrors = true;
    errorCode.compareAndSet(/*expect=*/ null, /*update=*/ e.getDetailedExitCode());
  }

  /**
   * Returns true iff any errors (such as missing targets or packages, or rules with errors) have
   * been encountered during any work.
   *
   * <p>Not thread-safe; do not call during visitation.
   *
   * @return true iff no errors (such as missing targets or packages, or rules with errors) have
   *     been encountered during any work.
   */
  public boolean hasErrors() {
    return hasErrors;
  }

  /** Returns the first {@link DetailedExitCode} encountered, or {@code null} if there were none. */
  @Nullable
  public DetailedExitCode getDetailedExitCode() {
    return errorCode.get();
  }

  @Override
  public void edge(Target from, Attribute attribute, Target to) {
    // No-op.
  }

  @Override
  public void node(Target node) {
    if (node.getPackage().containsErrors()
        || ((node instanceof Rule) && ((Rule) node).containsErrors())) {
      this.hasErrors = true;
      FailureDetail failureDetail = node.getPackage().getFailureDetail();
      if (failureDetail != null) {
        errorCode.compareAndSet(/*expect=*/ null, /*update=*/ DetailedExitCode.of(failureDetail));
      }
    }
  }
}
