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

import static org.junit.Assert.assertTrue;

import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.R8;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.FrameInspector;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import org.apache.harmony.jpda.tests.framework.jdwp.Value;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/** Tests local variable information. */
@RunWith(Parameterized.class)
public class BreakPointEventsTestRunner extends DebugTestBase {

  public static final Class<BreakPointEventsTest> CLASS = BreakPointEventsTest.class;
  public static final String FILE = CLASS.getSimpleName() + ".java";

  private static Path getClassFilePath() {
    return ToolHelper.getClassFileForTestClass(CLASS);
  }

  public static DebugTestConfig cfConfig() {
    return new CfDebugTestConfig(ToolHelper.getClassPathForTests());
  }

  public static DebugTestConfig d8Config() {
    return new D8DebugTestConfig().compileAndAdd(getStaticTemp(), getClassFilePath());
  }

  public static DebugTestConfig r8CfConfig() throws Exception {
    Path outCf = getStaticTemp().getRoot().toPath().resolve("cf.jar");
    R8.run(
        R8Command.builder()
            .setMode(CompilationMode.DEBUG)
            .addProgramFiles(getClassFilePath())
            .addLibraryFiles(ToolHelper.getJava8RuntimeJar())
            .setProgramConsumer(new ClassFileConsumer.ArchiveConsumer(outCf))
            .build());
    return new CfDebugTestConfig(ToolHelper.getClassPathForTests()).addPaths(outCf);
  }

  public void printConfig(String name, DebugTestConfig config) throws Exception {
    new DebugStreamComparator()
        .add(name, streamDebugTest(config, CLASS.getCanonicalName(), NO_FILTER))
        .setPrintStates(true)
        .setPrintMethod(true)
        .setPrintVariables(true)
        .setFilter(s -> s.getSourceFile().equals(FILE))
        .run();
  }

  // The main method will single-step each configuration of the test. It cannot be made a test as
  // the event streams are unequal due to ART vs JVM line change on return and DX incorrect locals.
  public static void main(String[] args) throws Exception {
    getStaticTemp().create();
    try {
      BreakPointEventsTestRunner runner = new BreakPointEventsTestRunner("unused name");
      System.out.println("\n============== CF single stepping: ");
      runner.printConfig("CF", cfConfig());
      System.out.println("\n============== D8 single stepping: ");
      runner.printConfig("D8", d8Config());
    } finally {
      getStaticTemp().delete();
    }
  }

  @Parameters(name = "{0}")
  public static Collection<String> configs() {
    return Arrays.asList("CF", "D8", "R8/CF");
  }

  private final DebugTestConfig config;

  public BreakPointEventsTestRunner(String name) throws Exception {
    if (name.equals("CF")) {
      config = cfConfig();
    } else if (name.equals("D8")) {
      config = d8Config();
    } else {
      assert name.equals("R8/CF");
      config = r8CfConfig();
    }
  }

  @Test
  public void testSingleLineDeclarations() throws Throwable {
    int bLine = 11;
    Value bValueOne = Value.createInt(1);
    Value bValueTwo = Value.createInt(2);
    runDebugTest(
        config,
        CLASS.getCanonicalName(),
        // Install breakpoint on b which is hit 6 times during execution.
        breakpoint(CLASS.getCanonicalName(), "b"),
        // First set of declarations will have respectively {}, {x}, and {x,y} visible in the frame.
        run(),
        checkLine(FILE, bLine),
        inspect(
            i -> {
              FrameInspector frame = i.getFrame(1);
              frame.checkNoLocal("x");
              frame.checkNoLocal("y");
              frame.checkNoLocal("z");
            }),
        run(),
        checkLine(FILE, bLine),
        inspect(
            i -> {
              FrameInspector frame = i.getFrame(1);
              frame.checkLocal("x", bValueOne);
              frame.checkNoLocal("y");
              frame.checkNoLocal("z");
            }),
        run(),
        checkLine(FILE, bLine),
        inspect(
            i -> {
              FrameInspector frame = i.getFrame(1);
              frame.checkLocal("x", bValueOne);
              frame.checkLocal("y", bValueOne);
              frame.checkNoLocal("z");
            }),
        // Second set of declarations should appear the same, only with another value.
        run(),
        checkLine(FILE, bLine),
        inspect(
            i -> {
              FrameInspector frame = i.getFrame(1);
              // This fails on DX compiled output since x will appear visible here.
              frame.checkNoLocal("x");
              frame.checkNoLocal("y");
              frame.checkNoLocal("z");
            }),
        run(),
        checkLine(FILE, bLine),
        inspect(
            i -> {
              FrameInspector frame = i.getFrame(1);
              frame.checkLocal("x", bValueTwo);
              frame.checkNoLocal("y");
              frame.checkNoLocal("z");
            }),
        run(),
        checkLine(FILE, bLine),
        inspect(
            i -> {
              FrameInspector frame = i.getFrame(1);
              frame.checkLocal("x", bValueTwo);
              frame.checkLocal("y", bValueTwo);
              frame.checkNoLocal("z");
            }),
        // Install additonal breakpoint on return to main so we identify program execution ended.
        breakpoint(CLASS.getCanonicalName(), "main", 22),
        run(),
        checkLine(FILE, 22),
        run());
  }
}
