// Copyright (c) 2018, 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;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;

import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.naming.retrace.StackTrace;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ThrowingConsumer;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.io.IOException;
import java.io.PrintStream;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Predicate;
import org.hamcrest.Matcher;

public abstract class SingleTestRunResult<RR extends SingleTestRunResult<RR>>
    extends TestRunResult<RR> {
  protected final AndroidApp app;
  private final TestRuntime runtime;
  private final ProcessResult result;
  private boolean executedSatisfyingRuntime = false;

  public SingleTestRunResult(AndroidApp app, TestRuntime runtime, ProcessResult result) {
    this.app = app;
    this.runtime = runtime;
    this.result = result;
  }

  public boolean isR8TestRunResult() {
    return false;
  }

  public AndroidApp app() {
    return app;
  }

  public ProcessResult getResult() {
    return result;
  }

  public String getStdOut() {
    return result.stdout;
  }

  public <E extends Throwable> RR inspectStdOut(ThrowingConsumer<String, E> consumer) throws E {
    consumer.accept(getStdOut());
    return self();
  }

  public String getStdErr() {
    return result.stderr;
  }

  public StackTrace getStackTrace() {
    if (runtime.isDex()) {
      return StackTrace.extractFromArt(getStdErr(), runtime.asDex().getVm());
    } else {
      return StackTrace.extractFromJvm(getStdErr());
    }
  }

  public int getExitCode() {
    return result.exitCode;
  }

  @Override
  public RR assertSuccess() {
    assertEquals(errorMessage("Expected run to succeed."), 0, result.exitCode);
    return self();
  }

  @Override
  public RR assertStdoutMatches(Matcher<String> matcher) {
    assertThat(errorMessage("Run stdout incorrect.", matcher.toString()), result.stdout, matcher);
    return self();
  }

  @Override
  public RR assertFailure() {
    assertNotEquals(errorMessage("Expected run to fail."), 0, result.exitCode);
    return self();
  }

  @Override
  public RR assertStderrMatches(Matcher<String> matcher) {
    assertThat(errorMessage("Run stderr incorrect.", matcher.toString()), result.stderr, matcher);
    return self();
  }

  protected CodeInspector internalGetCodeInspector() throws IOException {
    assertNotNull(app);
    return new CodeInspector(app);
  }

  public CodeInspector inspector() throws IOException, ExecutionException {
    // Inspection post run implies success. If inspection of an invalid program is needed it should
    // be done on the compilation result or on the input.
    assertSuccess();
    return internalGetCodeInspector();
  }

  @Override
  public <E extends Throwable> RR inspect(ThrowingConsumer<CodeInspector, E> consumer)
      throws IOException, ExecutionException, E {
    CodeInspector inspector = inspector();
    consumer.accept(inspector);
    return self();
  }

  public <E extends Throwable> RR inspectFailure(ThrowingConsumer<CodeInspector, E> consumer)
      throws IOException, E {
    assertFailure();
    CodeInspector inspector = internalGetCodeInspector();
    consumer.accept(inspector);
    return self();
  }

  public <E extends Throwable> RR inspectStackTrace(ThrowingConsumer<StackTrace, E> consumer)
      throws E {
    consumer.accept(getStackTrace());
    return self();
  }

  public RR disassemble(PrintStream ps) throws IOException, ExecutionException {
    ToolHelper.disassemble(app, ps);
    return self();
  }

  @Override
  public RR disassemble() throws IOException, ExecutionException {
    return disassemble(System.out);
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    appendInfo(builder);
    return builder.toString();
  }

  String errorMessage(String message) {
    return errorMessage(message, null);
  }

  String errorMessage(String message, String expected) {
    StringBuilder builder = new StringBuilder(message).append('\n');
    if (expected != null) {
      if (expected.contains(System.lineSeparator())) {
        builder.append("EXPECTED:").append(System.lineSeparator()).append(expected);
      } else {
        builder.append("EXPECTED: ").append(expected);
      }
      builder.append(System.lineSeparator());
    }
    appendInfo(builder);
    return builder.toString();
  }

  private void appendInfo(StringBuilder builder) {
    builder.append("APPLICATION: ");
    appendApplication(builder);
    builder.append('\n');
    appendProcessResult(builder);
  }

  private void appendApplication(StringBuilder builder) {
    builder.append(app == null ? "<default>" : app.toString());
  }

  private void appendProcessResult(StringBuilder builder) {
    builder.append("COMMAND: ").append(result.command).append('\n').append(result);
  }

  public RR writeProcessResult(PrintStream ps) {
    StringBuilder sb = new StringBuilder();
    appendProcessResult(sb);
    ps.println(sb.toString());
    return self();
  }

  public RR forDexRuntimeSatisfying(Predicate<DexVm.Version> predicate, Consumer<RR> action) {
    if (runtime.isDex() && predicate.test(runtime.asDex().getVm().getVersion())) {
      action.accept(self());
      executedSatisfyingRuntime = true;
    }
    return self();
  }

  public RR forCfRuntime(Consumer<RR> action) {
    if (runtime.isCf()) {
      action.accept(self());
      executedSatisfyingRuntime = true;
    }
    return self();
  }

  public RR otherwise(Consumer<RR> action) {
    if (!executedSatisfyingRuntime) {
      action.accept(self());
    }
    return self();
  }
}
