// 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.bisect;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersBuilder;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.bisect.BisectOptions.Result;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class BisectTest extends TestBase {

  @Parameters(name = "{0}")
  public static TestParametersCollection parameters() {
    return TestParametersBuilder.builder().withNoneRuntime().build();
  }

  private final TestParameters parameters;

  public BisectTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  private final String[] CLASSES = {"A", "B", "C", "D", "E", "F", "G", "H"};
  private final String ERRONEOUS_CLASS = "F";
  private final String ERRONEOUS_METHOD = "foo";
  private final String VALID_METHOD = "bar";

  // Set during build to more easily inspect later.
  private MethodSignature erroneousMethodSignature = null;

  // Build "good" application with no method in "F".
  AndroidApp buildGood() throws Exception {
    SmaliBuilder builderGood = new SmaliBuilder();
    for (String clazz : CLASSES) {
      builderGood.addClass(clazz);
      builderGood.addStaticMethod(
          "void", VALID_METHOD, ImmutableList.of(), 0, "return-void");
    }
    return AndroidApp.builder().addDexProgramData(builderGood.compile(), Origin.unknown()).build();
  }

  AndroidApp buildBad() throws Exception {
    // Build "bad" application with a method "foo" in "F".
    SmaliBuilder builderBad = new SmaliBuilder();
    for (String clazz : CLASSES) {
      builderBad.addClass(clazz);
      if (clazz.equals(ERRONEOUS_CLASS)) {
        erroneousMethodSignature = builderBad.addStaticMethod(
            "void", ERRONEOUS_METHOD, ImmutableList.of(), 0, "return-void");
      } else {
        builderBad.addStaticMethod(
            "void", VALID_METHOD, ImmutableList.of(), 0, "return-void");
      }
    }
    return AndroidApp.builder().addDexProgramData(builderBad.compile(), Origin.unknown()).build();
  }

  @Test
  public void bisectWithExternalCommand() throws Exception {
    AndroidApp goodInput = buildGood();
    AndroidApp badInput = buildBad();
    ExecutorService executor = Executors.newWorkStealingPool();
    DexProgramClass clazz = null;
    Path stateFile = temp.newFolder().toPath().resolve("state.txt");
    try {
      Result lastResult = Result.UNKNOWN;
      while (clazz == null) {
        InternalOptions options = new InternalOptions();
        Timing timing = new Timing("bisect-test");
        DexApplication appGood = new ApplicationReader(goodInput, options, timing).read();
        DexApplication appBad = new ApplicationReader(badInput, options, timing).read();
        BisectState state = new BisectState(appGood, appBad, stateFile);
        state.read();
        if (lastResult != Result.UNKNOWN) {
          state.setPreviousResult(lastResult);
        }
        Path output = temp.newFolder().toPath();
        clazz = Bisect.run(state, null, output, executor);
        state.write();
        if (clazz == null) {
          lastResult = command(new CodeInspector(output.resolve("classes.dex")));
        }
      }
    } finally {
      executor.shutdown();
    }
    assertEquals(clazz.type.toString(), ERRONEOUS_CLASS);
  }

  @Test
  public void bisectWithInternalCommand() throws Exception {
    InternalOptions options = new InternalOptions();
    Timing timing = new Timing("bisect-test");
    DexApplication appGood = new ApplicationReader(buildGood(), options, timing).read();
    DexApplication appBad = new ApplicationReader(buildBad(), options, timing).read();
    ExecutorService executor = Executors.newWorkStealingPool();
    try {
      BisectState state = new BisectState(appGood, appBad, null);
      DexProgramClass clazz =
          Bisect.run(
              state, app -> command(new CodeInspector(app)), temp.newFolder().toPath(), executor);
      assertEquals(clazz.type.toString(), ERRONEOUS_CLASS);
    } finally {
      executor.shutdown();
    }
  }

  private Result command(CodeInspector inspector) {
    if (inspector
        .clazz(ERRONEOUS_CLASS)
        .method(erroneousMethodSignature.returnType,
            erroneousMethodSignature.name,
            erroneousMethodSignature.parameterTypes)
        .isPresent()) {
      return Result.BAD;
    }
    return Result.GOOD;
  }
}
