// 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.ir.analysis;

import static org.junit.Assert.fail;

import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.util.function.Consumer;
import java.util.function.Predicate;
import org.junit.Before;

public abstract class AnalysisTestBase extends TestBase {

  public AppView<?> appView;
  private final AndroidApp app;
  private final String className;
  protected final TestParameters parameters;

  public AnalysisTestBase(TestParameters parameters, Class<?> clazz) throws Exception {
    if (parameters.isCfRuntime()) {
      this.app =
          buildClassesWithTestingAnnotations(clazz)
              .addLibraryFile(parameters.getDefaultRuntimeLibrary())
              .build();
    } else {
      D8TestCompileResult compileResult =
          testForD8()
              .release()
              .setMinApi(parameters.getApiLevel())
              .addProgramClasses(clazz)
              .addTestingAnnotationsAsProgramClasses()
              .compile();
      this.app =
          AndroidApp.builder(compileResult.getApp())
              .addLibraryFile(parameters.getDefaultRuntimeLibrary())
              .build();
    }
    this.parameters = parameters;
    this.className = clazz.getTypeName();
  }

  public AnalysisTestBase(TestParameters parameters, Class<?> mainClass, Class<?>... classes)
      throws Exception {
    this(parameters, mainClass.getTypeName(), classes);
  }

  public AnalysisTestBase(
      TestParameters parameters, String mainClassName, Class<?>... classes) throws Exception {
    if (parameters.isCfRuntime()) {
      this.app =
          buildClassesWithTestingAnnotations(classes)
              .addLibraryFile(parameters.getDefaultRuntimeLibrary())
              .build();
    } else {
      D8TestCompileResult compileResult =
          testForD8()
              .release()
              .setMinApi(parameters.getApiLevel())
              .addProgramClasses(classes)
              .addTestingAnnotationsAsProgramClasses()
              .compile();
      this.app =
          AndroidApp.builder(compileResult.getApp())
              .addLibraryFile(parameters.getDefaultRuntimeLibrary())
              .build();
    }
    this.parameters = parameters;
    this.className = mainClassName;
  }

  public AnalysisTestBase(TestParameters parameters, AndroidApp app, String className) {
    this.parameters = parameters;
    this.app = app;
    this.className = className;
  }

  public void configure(InternalOptions options) {}

  @Before
  public void setup() throws Exception {
    appView = computeAppViewWithLiveness(app, null, this::configure);
  }

  public void buildAndCheckIR(String methodName, Consumer<IRCode> irInspector) {
    CodeInspector inspector = new CodeInspector(appView.appInfo().app());
    MethodSubject methodSubject = inspector.clazz(className).uniqueMethodWithName(methodName);
    irInspector.accept(methodSubject.buildIR(appView));
  }

  @SuppressWarnings("unchecked")
  public static <T extends Instruction> T getMatchingInstruction(
      IRCode code, Predicate<Instruction> predicate) {
    Instruction result = null;
    for (Instruction instruction : code.instructions()) {
      if (predicate.test(instruction)) {
        if (result != null) {
          fail();
        }
        result = instruction;
      }
    }
    if (result == null) {
      fail();
    }
    return (T) result;
  }
}
