// 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.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.stream.Collectors;

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

  /**
   * 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 CrashFailureDetails() {}

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

  /**
   * Returns a {@link Crash}-type {@link FailureDetail} with {@link Crash.Code#CRASH_UNKNOWN}, with
   * its cause chain filled out.
   */
  public static FailureDetail forThrowable(Throwable throwable) {
    Crash.Builder crashBuilder =
        Crash.newBuilder()
            .setCode(
                (getRootCauseToleratingCycles(throwable) instanceof OutOfMemoryError)
                    ? Crash.Code.CRASH_OOM
                    : 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;
  }
}
