// Copyright 2020 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.util;

import com.google.common.base.Ascii;
import com.google.common.base.Throwables;
import com.google.common.collect.Sets;
import com.google.common.flogger.GoogleLogger;
import com.google.devtools.build.lib.server.FailureDetails;
import com.google.devtools.build.lib.server.FailureDetails.Crash;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.server.FailureDetails.ThrowableOrBuilder;
import java.util.Set;
import java.util.function.BooleanSupplier;
import java.util.stream.Collectors;

/** Factory methods for producing {@link Crash}-type {@link FailureDetail} messages. */
public class CrashFailureDetails {

  private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();

  /**
   * Max message length in {@link FailureDetails.Throwable} submessage, anything beyond this is
   * truncated.
   */
  private static final int MAX_THROWABLE_MESSAGE_LENGTH = 2000;

  /**
   * At most this many {@link FailureDetails.Throwable} messages will be specified by a {@link
   * Crash} submessage.
   */
  private static final int MAX_CAUSE_CHAIN_SIZE = 5;

  /**
   * At most this many stack trace element strings will be specified by a {@link
   * FailureDetails.Throwable} submessage.
   */
  private static final int MAX_STACK_TRACE_SIZE = 1000;

  private static BooleanSupplier oomDetector = () -> false;

  private CrashFailureDetails() {}

  /** Registers a predicate to use for more aggressive {@link OutOfMemoryError} detection. */
  public static void setOomDetector(BooleanSupplier oomDetector) {
    CrashFailureDetails.oomDetector = oomDetector;
  }

  /** Returns whether an {@link OutOfMemoryError} was detected. */
  public static boolean oomDetected() {
    return oomDetector.getAsBoolean();
  }

  public static DetailedExitCode detailedExitCodeForThrowable(Throwable throwable) {
    return DetailedExitCode.of(forThrowable(throwable));
  }

  /** Returns a {@link Crash}-type {@link FailureDetail} with its cause chain filled out. */
  public static FailureDetail forThrowable(Throwable throwable) {
    Crash.Builder crashBuilder = Crash.newBuilder();
    if (getRootCauseToleratingCycles(throwable) instanceof OutOfMemoryError) {
      crashBuilder.setCode(Crash.Code.CRASH_OOM);
    } else if (oomDetected()) {
      logger.atWarning().log("Classifying non-OOM crash as OOM");
      crashBuilder.setCode(Crash.Code.CRASH_OOM).setOomDetectorOverride(true);
    } else {
      crashBuilder.setCode(Crash.Code.CRASH_UNKNOWN);
    }
    addCause(crashBuilder, throwable, Sets.newIdentityHashSet());
    return FailureDetail.newBuilder()
        .setMessage("Crashed: " + joinSummarizedCauses(crashBuilder))
        .setCrash(crashBuilder)
        .build();
  }

  private static String joinSummarizedCauses(Crash.Builder crashBuilder) {
    return crashBuilder.getCausesOrBuilderList().stream()
        .map(CrashFailureDetails::summarizeCause)
        .collect(Collectors.joining(", "));
  }

  private static String summarizeCause(ThrowableOrBuilder throwableOrBuilder) {
    return String.format(
        "(%s) %s", throwableOrBuilder.getThrowableClass(), throwableOrBuilder.getMessage());
  }

  private static void addCause(
      Crash.Builder crashBuilder, Throwable throwable, Set<Object> addedThrowables) {
    addedThrowables.add(throwable);

    crashBuilder.addCauses(getThrowable(throwable));

    Throwable cause = throwable.getCause();
    if (cause == null
        || addedThrowables.contains(cause)
        || crashBuilder.getCausesOrBuilderList().size() >= MAX_CAUSE_CHAIN_SIZE) {
      return;
    }
    addCause(crashBuilder, cause, addedThrowables);
  }

  private static FailureDetails.Throwable getThrowable(Throwable throwable) {
    String throwableMessage =
        Ascii.truncate(
            throwable.getMessage() != null ? throwable.getMessage() : "",
            MAX_THROWABLE_MESSAGE_LENGTH,
            "[truncated]");
    FailureDetails.Throwable.Builder throwableBuilder =
        FailureDetails.Throwable.newBuilder()
            .setMessage(throwableMessage)
            .setThrowableClass(throwable.getClass().getName());
    StackTraceElement[] stackTrace = throwable.getStackTrace();
    for (StackTraceElement stackTraceElement : stackTrace) {
      if (throwableBuilder.getStackTraceList().size() >= MAX_STACK_TRACE_SIZE) {
        break;
      }
      throwableBuilder.addStackTrace(stackTraceElement.toString());
    }
    return throwableBuilder.build();
  }

  /**
   * Returns the innermost cause of {@code throwable}. The first throwable in a chain provides
   * context from when the error or exception was initially detected. Example usage:
   *
   * <pre>
   * assertEquals("Unable to assign a customer id", Throwables.getRootCause(e).getMessage());
   * </pre>
   *
   * Cloned from {@link Throwables#getRootCause} with a modification to return an arbitrary element
   * of the cycle rather than throw if there is a causal cycle.
   */
  private static Throwable getRootCauseToleratingCycles(Throwable throwable) {
    // Keep a second pointer that slowly walks the causal chain. If the fast pointer ever catches
    // the slower pointer, then there's a loop.
    Throwable slowPointer = throwable;
    boolean advanceSlowPointer = false;

    Throwable cause;
    while ((cause = throwable.getCause()) != null) {
      throwable = cause;

      if (throwable == slowPointer) {
        // There's a cycle: choose an arbitrary element in that cycle.
        return throwable;
      }
      if (advanceSlowPointer) {
        slowPointer = slowPointer.getCause();
      }
      advanceSlowPointer = !advanceSlowPointer; // only advance every other iteration
    }
    return throwable;
  }
}
