// 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.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 {

  /**
   * 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: " + joinCauseMessages(crashBuilder))
        .setCrash(crashBuilder)
        .build();
  }

  private static String joinCauseMessages(Crash.Builder crashBuilder) {
    return crashBuilder.getCausesOrBuilderList().stream()
        .map(ThrowableOrBuilder::getMessage)
        .collect(Collectors.joining(", "));
  }

  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 = throwable.getMessage() != null ? throwable.getMessage() : "";
    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;
  }
}
