// Copyright (c) 2020, 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 com.android.tools.r8.utils.ConsumerUtils.emptyThrowingConsumer;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;

import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.ThrowingConsumer;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import org.hamcrest.Matcher;

/**
 * Abstract base for checking the result of executing (test) program(s).
 *
 * <p>All methods defined on this base must generalize to allow checking of multiple run results
 * simultaneously. For methods on single runs see the SingleTestRunResult subclass.
 */
public abstract class TestRunResult<RR extends TestRunResult<RR>> {

  abstract RR self();

  public abstract RR assertSuccess();

  public abstract RR assertStdoutMatches(Matcher<String> matcher);

  public abstract RR assertFailure();

  public abstract RR assertStderrMatches(Matcher<String> matcher);

  public abstract <E extends Throwable> RR inspect(ThrowingConsumer<CodeInspector, E> consumer)
      throws IOException, ExecutionException, E;

  public abstract RR disassemble() throws IOException, ExecutionException;

  public <E extends Throwable> RR apply(ThrowingConsumer<RR, E> fn) throws E {
    fn.accept(self());
    return self();
  }

  public <T extends Throwable> RR applyIf(boolean condition, ThrowingConsumer<RR, T> thenConsumer)
      throws T {
    return applyIf(condition, thenConsumer, emptyThrowingConsumer());
  }

  public <S extends Throwable, T extends Throwable> RR applyIf(
      boolean condition, ThrowingConsumer<RR, S> thenConsumer, ThrowingConsumer<RR, T> elseConsumer)
      throws S, T {
    return applyIf(
        condition,
        thenConsumer,
        true,
        elseConsumer,
        r -> {
          assert false;
        });
  }

  public <S extends Throwable, T extends Throwable, U extends Throwable> RR applyIf(
      boolean condition1,
      ThrowingConsumer<RR, S> thenConsumer1,
      boolean condition2,
      ThrowingConsumer<RR, T> thenConsumer2,
      ThrowingConsumer<RR, U> elseConsumer)
      throws S, T, U {
    return applyIf(
        condition1,
        thenConsumer1,
        condition2,
        thenConsumer2,
        true,
        elseConsumer,
        r -> {
          assert false;
        });
  }

  public <S extends Throwable, T extends Throwable, U extends Throwable, V extends Throwable>
      RR applyIf(
          boolean condition1,
          ThrowingConsumer<RR, S> thenConsumer1,
          boolean condition2,
          ThrowingConsumer<RR, T> thenConsumer2,
          boolean condition3,
          ThrowingConsumer<RR, U> thenConsumer3,
          ThrowingConsumer<RR, V> elseConsumer)
          throws S, T, U, V {
    if (condition1) {
      thenConsumer1.accept(self());
    } else if (condition2) {
      thenConsumer2.accept(self());
    } else if (condition3) {
      thenConsumer3.accept(self());
    } else {
      elseConsumer.accept(self());
    }
    return self();
  }

  public <S> S map(Function<RR, S> fn) {
    return fn.apply(self());
  }

  public RR assertSuccessWithOutputThatMatches(Matcher<String> matcher) {
    assertStdoutMatches(matcher);
    return assertSuccess();
  }

  public RR assertSuccessWithOutput(String expected) {
    return assertSuccessWithOutputThatMatches(is(expected));
  }

  public RR assertSuccessWithEmptyOutput() {
    return assertSuccessWithOutput("");
  }

  public RR assertSuccessWithOutputLines(String... expected) {
    return assertSuccessWithOutputLines(Arrays.asList(expected));
  }

  public RR assertSuccessWithOutputLinesIf(boolean condition, String... expected) {
    return assertSuccessWithOutputLinesIf(condition, Arrays.asList(expected));
  }

  public RR assertSuccessWithOutputLinesIf(boolean condition, List<String> expected) {
    if (condition) {
      return assertSuccessWithOutputLines(expected);
    }
    return self();
  }

  public RR assertSuccessWithOutputLines(List<String> expected) {
    return assertSuccessWithOutput(StringUtils.lines(expected));
  }

  public RR assertFailureWithErrorThatMatches(Matcher<String> matcher) {
    assertStderrMatches(matcher);
    return assertFailure();
  }

  public RR assertFailureWithOutput(String expected) {
    assertStdoutMatches(is(expected));
    return assertFailure();
  }

  public RR assertFailureWithErrorThatThrows(Class<? extends Throwable> expectedError) {
    return assertFailureWithErrorThatMatches(containsString(expectedError.getName()));
  }

  public RR assertFailureWithErrorThatThrowsIf(
      boolean condition, Class<? extends Throwable> expectedError) {
    if (condition) {
      return assertFailureWithErrorThatThrows(expectedError);
    }
    return self();
  }
}
