// 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 com.android.tools.r8.naming.ClassNameMapper.MissingFileAction.MISSING_FILE_IS_EMPTY_MAP;

import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.Command;
import com.android.tools.r8.debug.DebugTestConfig.RuntimeKind;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/** Tests source file and line numbers on inlined methods. */
@RunWith(Parameterized.class)
public class DebugInfoWhenInliningTest extends DebugTestBase {

  public enum Config {
    CF,
    DEX_NO_FORCE_JUMBO,
    DEX_FORCE_JUMBO
  };

  private static final String CLASS_NAME = "Inlining1";
  private static final String SOURCE_FILE = "Inlining1.java";

  private DebugTestConfig makeConfig(
      LineNumberOptimization lineNumberOptimization,
      boolean writeProguardMap,
      RuntimeKind runtimeKind)
      throws Exception {
    DebugTestConfig config = null;
    Path outdir = temp.newFolder().toPath();
    Path outjar = outdir.resolve("r8_compiled.jar");
    R8Command.Builder builder =
        R8Command.builder()
            .addProgramFiles(DEBUGGEE_JAR)
            .setMode(CompilationMode.RELEASE)
            .addProguardConfiguration(
                ImmutableList.of(
                    "-keep class "
                        + CLASS_NAME
                        + " { public static void main(java.lang.String[]); }"),
                Origin.unknown())
            .setDisableMinification(true)
            .addProguardConfiguration(
                ImmutableList.of("-keepattributes SourceFile,LineNumberTable"), Origin.unknown());

    if (runtimeKind == RuntimeKind.DEX) {
      AndroidApiLevel minSdk = ToolHelper.getMinApiLevelForDexVm();
      builder
          .setMinApiLevel(minSdk.getLevel())
          .addLibraryFiles(ToolHelper.getAndroidJar(minSdk))
          .setOutput(outjar, OutputMode.DexIndexed);
      config = new DexDebugTestConfig(outjar);
    } else {
      assert (runtimeKind == RuntimeKind.CF);
      builder
          .setOutput(outjar, OutputMode.ClassFile)
          .addLibraryFiles(ToolHelper.getJava8RuntimeJar());
      config = new CfDebugTestConfig(outjar);
    }

    if (writeProguardMap) {
      Path proguardMapPath = outdir.resolve("proguard.map");
      builder.setProguardMapOutputPath(proguardMapPath);
      config.setProguardMap(proguardMapPath, MISSING_FILE_IS_EMPTY_MAP);
    }

    ToolHelper.runR8(
        builder.build(), options -> {
          options.lineNumberOptimization = lineNumberOptimization;
          options.testing.forceJumboStringProcessing = forceJumboStringProcessing;
          // TODO(b/117848700): Can we make these tests neutral to inlining threshold?
          // Also CF needs improvements here.
          options.inliningInstructionLimit = runtimeKind == RuntimeKind.CF ? 5 : 4;
        });

    return config;
  }

  private boolean forceJumboStringProcessing;
  private RuntimeKind runtimeKind;

  @Parameters(name = "config: {0}")
  public static Collection<Config> data() {
    return Arrays.asList(Config.values());
  }

  public DebugInfoWhenInliningTest(Config config) {
    this.forceJumboStringProcessing = config == Config.DEX_FORCE_JUMBO;
    this.runtimeKind = config == Config.CF ? RuntimeKind.CF : RuntimeKind.DEX;
  }

  @Test
  public void testEachLineNotOptimized() throws Throwable {
    // The reason why the not-optimized test contains half as many line numbers as the optimized
    // one:
    //
    // In the Java source (Inlining1) each call is duplicated. Since they end up on the same line
    // (innermost callee) the line numbers are actually 7, 7, 32, 32, ... but even if the positions
    // are emitted duplicated in the dex code, the debugger stops only when there's a change.
    int[] lineNumbers = {7, 32, 11, 7};
    testEachLine(makeConfig(LineNumberOptimization.OFF, false, runtimeKind), lineNumbers);
  }

  @Test
  public void testEachLineNotOptimizedWithMap() throws Throwable {
    // The reason why the not-optimized test contains half as many line numbers as the optimized
    // one:
    //
    // In the Java source (Inlining1) each call is duplicated. Since they end up on the same line
    // (innermost callee) the line numbers are actually 7, 7, 32, 32, ... but even if the positions
    // are emitted duplicated in the dex code, the debugger stops only when there's a change.
    int[] lineNumbers = {7, 32, 11, 7};
    testEachLine(makeConfig(LineNumberOptimization.OFF, true, runtimeKind), lineNumbers);
  }

  @Test
  public void testEachLineOptimized() throws Throwable {
    int[] lineNumbers = {1, 2, 3, 4, 5, 6, 7, 8};
    testEachLine(makeConfig(LineNumberOptimization.ON, false, runtimeKind), lineNumbers);
  }

  @Test
  public void testEachLineOptimizedWithMap() throws Throwable {
    int[] lineNumbers = {7, 7, 32, 32, 11, 11, 7, 7};
    List<List<SignatureAndLine>> inlineFramesList =
        ImmutableList.of(
            ImmutableList.of(
                new SignatureAndLine("void inlineThisFromSameFile()", 7),
                new SignatureAndLine("void main(java.lang.String[])", 19)),
            ImmutableList.of(
                new SignatureAndLine("void inlineThisFromSameFile()", 7),
                new SignatureAndLine("void main(java.lang.String[])", 20)),
            ImmutableList.of(
                new SignatureAndLine("void Inlining2.inlineThisFromAnotherFile()", 32),
                new SignatureAndLine("void main(java.lang.String[])", 21)),
            ImmutableList.of(
                new SignatureAndLine("void Inlining2.inlineThisFromAnotherFile()", 32),
                new SignatureAndLine("void main(java.lang.String[])", 22)),
            ImmutableList.of(
                new SignatureAndLine("void sameFileMultilevelInliningLevel2()", 11),
                new SignatureAndLine("void sameFileMultilevelInliningLevel1()", 15),
                new SignatureAndLine("void main(java.lang.String[])", 23)),
            ImmutableList.of(
                new SignatureAndLine("void sameFileMultilevelInliningLevel2()", 11),
                new SignatureAndLine("void sameFileMultilevelInliningLevel1()", 15),
                new SignatureAndLine("void main(java.lang.String[])", 24)),
            ImmutableList.of(
                new SignatureAndLine("void Inlining3.differentFileMultilevelInliningLevel2()", 7),
                new SignatureAndLine("void Inlining2.differentFileMultilevelInliningLevel1()", 36),
                new SignatureAndLine("void main(java.lang.String[])", 25)),
            ImmutableList.of(
                new SignatureAndLine("void Inlining3.differentFileMultilevelInliningLevel2()", 7),
                new SignatureAndLine("void Inlining2.differentFileMultilevelInliningLevel1()", 36),
                new SignatureAndLine("void main(java.lang.String[])", 26)));
    testEachLine(
        makeConfig(LineNumberOptimization.ON, true, runtimeKind), lineNumbers, inlineFramesList);
  }

  private void testEachLine(DebugTestConfig config, int[] lineNumbers) throws Throwable {
    testEachLine(config, lineNumbers, null);
  }

  private void testEachLine(
      DebugTestConfig config, int[] lineNumbers, List<List<SignatureAndLine>> inlineFramesList)
      throws Throwable {
    final String mainSignature = "([Ljava/lang/String;)V";

    List<Command> commands = new ArrayList<Command>();
    commands.add(breakpoint(CLASS_NAME, "main", mainSignature));
    commands.add(run());
    boolean first = true;
    assert inlineFramesList == null || inlineFramesList.size() == lineNumbers.length;
    for (int idx = 0; idx < lineNumbers.length; ++idx) {
      if (first) {
        first = false;
      } else {
        commands.add(stepOver());
      }
      commands.add(checkMethod(CLASS_NAME, "main", mainSignature));
      commands.add(checkLine(SOURCE_FILE, lineNumbers[idx]));
      if (inlineFramesList != null) {
        commands.add(checkInlineFrames(inlineFramesList.get(idx)));
      }
    }
    commands.add(run());
    runDebugTest(config, CLASS_NAME, commands);
  }
}
