// 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 <E extends Throwable> RR inspectFailure(
      ThrowingConsumer<CodeInspector, E> consumer) throws IOException, 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 assertFailureWithErrorThatMatchesIf(boolean condition, Matcher<String> matcher) {
    if (condition) {
      assertStderrMatches(matcher);
      return assertFailure();
    }
    return self();
  }

  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();
  }
}
