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

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.KotlinTestParameters;
import com.android.tools.r8.TestParameters;
import java.util.List;
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;

@RunWith(Parameterized.class)
public class KotlinTest extends KotlinDebugTestBase {

  private final TestParameters parameters;
  private final KotlinTestParameters kotlinParameters;

  @Parameters(name = "{0}, {1}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withDexRuntimes().withAllApiLevels().build(),
        getKotlinTestParameters().withAllCompilersAndTargetVersions().build());
  }

  public KotlinTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
    this.parameters = parameters;
    this.kotlinParameters = kotlinParameters;
  }

  protected KotlinD8Config getD8Config() {
    return KotlinD8Config.build(kotlinParameters, parameters.getApiLevel());
  }

  // TODO(shertz) simplify test
  // TODO(shertz) add more variables ?
  @Test
  public void testStepOver() throws Throwable {
    runDebugTest(
        getD8Config(),
        "KotlinApp",
        breakpoint("KotlinApp$Companion", "main"),
        run(),
        inspect(s -> {
          assertEquals("KotlinApp$Companion", s.getClassName());
          assertEquals("KotlinApp.kt", s.getSourceFile());
          assertEquals(24, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("args");
          checkNoLocal("instance");
        }),
        stepOver(),
        inspect(s -> {
          assertEquals(25, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("args");
          s.checkLocal("instance");
        }),
        stepOver(),
        inspect(s -> {
          assertEquals(26, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("args");
          s.checkLocal("instance");
        }),
        run());
  }

  @Test
  public void testStepIntoAndOut() throws Throwable {
    runDebugTest(
        getD8Config(),
        "KotlinApp",
        breakpoint("KotlinApp$Companion", "main"),
        run(),
        inspect(s -> {
          assertEquals("KotlinApp$Companion", s.getClassName());
          assertEquals("KotlinApp.kt", s.getSourceFile());
          assertEquals(24, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("args");
          checkNoLocal("instance");
        }),
        stepOver(),
        inspect(s -> {
          assertEquals(25, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("args");
          s.checkLocal("instance");
        }),
        // Step into 1st invoke of ifElse
        stepInto(),
        inspect(s -> {
          assertEquals("KotlinApp", s.getClassName());
          assertEquals("KotlinApp.kt", s.getSourceFile());
          assertEquals(8, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("cond", Value.createBoolean(true));
          checkNoLocal("a");
          checkNoLocal("b");
          checkNoLocal("c");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals("KotlinApp", s.getClassName());
          assertEquals(9, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("cond", Value.createBoolean(true));
          s.checkLocal("a", Value.createInt(10));
          checkNoLocal("b");
          checkNoLocal("c");
        }),
        stepInto(),
        inspect(s -> {
          // We should be into the 'then' statement.
          assertEquals("KotlinApp", s.getClassName());
          assertEquals(10, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("cond", Value.createBoolean(true));
          s.checkLocal("a", Value.createInt(10));
          checkNoLocal("b");
          checkNoLocal("c");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals("KotlinApp", s.getClassName());
          assertEquals(11, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("cond", Value.createBoolean(true));
          s.checkLocal("a", Value.createInt(10));
          s.checkLocal("b", Value.createInt(20));
          checkNoLocal("c");
        }),
        // Go back to the main method
        stepOut(),
        inspect(s -> {
          assertEquals("KotlinApp$Companion", s.getClassName());
          assertEquals("KotlinApp.kt", s.getSourceFile());
          assertEquals(26, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("args");
          checkNoLocal("instance");
        }),
        // Step into 2nd invoke of ifElse
        stepInto(),
        inspect(s -> {
          assertEquals("KotlinApp", s.getClassName());
          assertEquals("KotlinApp.kt", s.getSourceFile());
          assertEquals(8, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("cond", Value.createBoolean(false));
          checkNoLocal("a");
          checkNoLocal("b");
          checkNoLocal("c");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals("KotlinApp", s.getClassName());
          assertEquals(9, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("cond", Value.createBoolean(false));
          s.checkLocal("a", Value.createInt(10));
          checkNoLocal("b");
          checkNoLocal("c");
        }),
        stepInto(),
        inspect(s -> {
          // We should be into the 'else' statement this time.
          assertEquals("KotlinApp", s.getClassName());
          assertEquals(13, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("cond", Value.createBoolean(false));
          s.checkLocal("a", Value.createInt(10));
          checkNoLocal("b");
          checkNoLocal("c");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals("KotlinApp", s.getClassName());
          assertEquals(14, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("cond", Value.createBoolean(false));
          s.checkLocal("a", Value.createInt(10));
          checkNoLocal("b");
          s.checkLocal("c", Value.createInt(5));
        }),
        run());
  }

}
