// 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.bugreport.BugReport;
import com.google.devtools.build.lib.bugreport.BugReport.NonFatalBugReport;
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(/*expectedValue=*/ null, /*newValue=*/ 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(
            /*expectedValue=*/ null, /*newValue=*/ DetailedExitCode.of(failureDetail));
      } else {
        BugReport.sendBugReport(new UndetailedErrorFromPackageException(node));
      }
    }
  }

  private static final class UndetailedErrorFromPackageException extends RuntimeException
      implements NonFatalBugReport {
    UndetailedErrorFromPackageException(Target node) {
      super("Undetailed error from package: " + node);
    }
  }
}
