// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.utils;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.Version;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.position.Position;
import com.google.common.collect.ObjectArrays;
import java.io.IOException;
import java.nio.file.FileSystemException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public abstract class ExceptionUtils {

  public static String getMainStackTrace() {
    return Thread.getAllStackTraces().entrySet().stream()
        .filter(x -> x.getKey().getName().equals("main"))
        .map(x -> x.getValue())
        .flatMap(x -> Stream.of(x))
        .map(x -> x.toString())
        .collect(Collectors.joining(System.lineSeparator()));
  }

  public static void withConsumeResourceHandler(
      Reporter reporter, StringConsumer consumer, String data) {
    withConsumeResourceHandler(reporter, handler -> consumer.accept(data, handler));
  }

  public static void withFinishedResourceHandler(Reporter reporter, StringConsumer consumer) {
    withConsumeResourceHandler(reporter, consumer::finished);
  }

  public static void withConsumeResourceHandler(
      Reporter reporter, Consumer<DiagnosticsHandler> consumer) {
    // Unchecked exceptions simply propagate out, aborting the compilation forcefully.
    consumer.accept(reporter);
    // Fail fast for now. We might consider delaying failure since consumer failure does not affect
    // the compilation. We might need to be careful to correctly identify errors so as to exit
    // compilation with an error code.
    reporter.failIfPendingErrors();
  }

  public interface CompileAction {
    void run() throws IOException, CompilationError, ResourceException;
  }

  public static void withD8CompilationHandler(Reporter reporter, CompileAction action)
      throws CompilationFailedException {
    withCompilationHandler(reporter, action);
  }

  public static void withR8CompilationHandler(Reporter reporter, CompileAction action)
      throws CompilationFailedException {
    withCompilationHandler(reporter, action);
  }

  public static void withMainDexListHandler(
      Reporter reporter, CompileAction action) throws CompilationFailedException {
    withCompilationHandler(reporter, action);
  }

  public static void withCompilationHandler(Reporter reporter, CompileAction action)
      throws CompilationFailedException {
    try {
      action.run();
      reporter.failIfPendingErrors();
    } catch (Throwable e) {
      throw failCompilation(reporter, e);
    }
  }

  private static CompilationFailedException failCompilation(
      Reporter reporter, Throwable topMostException) {
    return failWithFakeEntry(
        reporter, topMostException, CompilationFailedException::new, AbortException.class);
  }

  public static <T extends Exception, A extends Exception> T failWithFakeEntry(
      DiagnosticsHandler diagnosticsHandler,
      Throwable topMostException,
      BiFunction<String, Throwable, T> newException,
      Class<A> abortException) {
    // Find inner-most cause of the failure and compute origin, position and reported for the path.
    boolean hasBeenReported = false;
    Origin origin = Origin.unknown();
    Position position = Position.UNKNOWN;
    List<Throwable> suppressed = new ArrayList<>();
    Throwable innerMostCause = topMostException;
    while (true) {
      hasBeenReported |= abortException.isAssignableFrom(innerMostCause.getClass());
      Origin nextOrigin = getOrigin(innerMostCause);
      if (nextOrigin != Origin.unknown()) {
        origin = nextOrigin;
      }
      Position nextPosition = getPosition(innerMostCause);
      if (nextPosition != Position.UNKNOWN) {
        position = nextPosition;
      }
      if (innerMostCause.getCause() == null || suppressed.contains(innerMostCause)) {
        break;
      }
      suppressed.add(innerMostCause);
      innerMostCause = innerMostCause.getCause();
    }
    // Add the full stack as a suppressed stack on the inner cause.
    if (topMostException != innerMostCause) {
      innerMostCause.addSuppressed(topMostException);
    }

    // If no abort is seen, the exception is not reported, so report it now.
    if (!hasBeenReported) {
      diagnosticsHandler.error(new ExceptionDiagnostic(innerMostCause, origin, position));
    }

    // Build the top-level compiler exception and version stack.
    StringBuilder message = new StringBuilder("Compilation failed to complete");
    if (position != Position.UNKNOWN) {
      message.append(", position: ").append(position);
    }
    if (origin != Origin.unknown()) {
      message.append(", origin: ").append(origin);
    }
    // Create the final exception object.
    T rethrow = newException.apply(message.toString(), innerMostCause);
    // Replace its stack by the cause stack and insert version info at the top.
    String filename = "Version_" + Version.LABEL + ".java";
    StackTraceElement versionElement =
        new StackTraceElement(Version.class.getSimpleName(), "fakeStackEntry", filename, 0);
    rethrow.setStackTrace(ObjectArrays.concat(versionElement, rethrow.getStackTrace()));
    return rethrow;
  }

  private static Origin getOrigin(Throwable e) {
    if (e instanceof IOException) {
      return extractIOExceptionOrigin((IOException) e);
    }
    if (e instanceof CompilationError) {
      return ((CompilationError) e).getOrigin();
    }
    if (e instanceof ResourceException) {
      return ((ResourceException) e).getOrigin();
    }
    if (e instanceof OriginAttachmentException) {
      return ((OriginAttachmentException) e).origin;
    }
    if (e instanceof AbortException) {
      return ((AbortException) e).getOrigin();
    }
    return Origin.unknown();
  }

  private static Position getPosition(Throwable e) {
    if (e instanceof CompilationError) {
      return ((CompilationError) e).getPosition();
    }
    if (e instanceof OriginAttachmentException) {
      return ((OriginAttachmentException) e).position;
    }
    if (e instanceof AbortException) {
      return ((AbortException) e).getPosition();
    }
    return Position.UNKNOWN;
  }

  public interface MainAction {
    void run() throws CompilationFailedException;
  }

  public static void withMainProgramHandler(MainAction action) {
    try {
      action.run();
    } catch (CompilationFailedException e) {
      printExitMessage(e.getCause());
      throw new RuntimeException(e);
    } catch (RuntimeException e) {
      printExitMessage(e);
      throw e;
    }
  }

  private static void printExitMessage(Throwable cause) {
    System.err.println(
        isExpectedException(cause)
            ? "Compilation failed"
            : "Compilation failed with an internal error.");
  }

  private static boolean isExpectedException(Throwable e) {
    return e instanceof CompilationError || e instanceof AbortException;
  }

  // We should try to avoid the use of this extraction as it signifies a point where we don't have
  // enough context to associate a specific origin with an IOException. Concretely, we should move
  // towards always catching IOException and rethrowing CompilationError with proper origins.
  private static Origin extractIOExceptionOrigin(IOException e) {
    if (e instanceof FileSystemException) {
      FileSystemException fse = (FileSystemException) e;
      if (fse.getFile() != null && !fse.getFile().isEmpty()) {
        return new PathOrigin(Paths.get(fse.getFile()));
      }
    }
    return Origin.unknown();
  }

  public static RuntimeException unwrapExecutionException(ExecutionException executionException) {
    return new RuntimeException(executionException);
  }

  public static void withOriginAttachmentHandler(Origin origin, Runnable action) {
    withOriginAndPositionAttachmentHandler(origin, Position.UNKNOWN, action);
  }

  public static <T> T withOriginAttachmentHandler(Origin origin, Supplier<T> action) {
    return withOriginAndPositionAttachmentHandler(origin, Position.UNKNOWN, action);
  }

  public static void withOriginAndPositionAttachmentHandler(
      Origin origin, Position position, Runnable action) {
    withOriginAndPositionAttachmentHandler(
        origin,
        position,
        () -> {
          action.run();
          return null;
        });
  }

  public static <T> T withOriginAndPositionAttachmentHandler(
      Origin origin, Position position, Supplier<T> action) {
    try {
      return action.get();
    } catch (RuntimeException e) {
      throw OriginAttachmentException.wrap(e, origin, position);
    }
  }

  private static class OriginAttachmentException extends RuntimeException {
    final Origin origin;
    final Position position;

    public static RuntimeException wrap(RuntimeException e, Origin origin, Position position) {
      return needsAttachment(e, origin, position)
          ? new OriginAttachmentException(e, origin, position)
          : e;
    }

    private OriginAttachmentException(RuntimeException e, Origin origin, Position position) {
      super(e);
      this.origin = origin;
      this.position = position;
    }

    private static boolean needsAttachment(RuntimeException e, Origin origin, Position position) {
      if (origin == Origin.unknown() && position == Position.UNKNOWN) {
        return false;
      }
      Origin existingOrigin = getOrigin(e);
      Position existingPosition = getPosition(e);
      return origin != existingOrigin || position != existingPosition;
    }
  }
}
