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

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.CfDebugTestConfig;
import com.android.tools.r8.debug.DebugTestBase;
import com.android.tools.r8.debug.DebugTestConfig;
import com.android.tools.r8.debug.DexDebugTestConfig;
import com.android.tools.r8.debug.classinit.ClassInitializationTest;
import com.android.tools.r8.debug.classinit.ClassInitializerEmpty;
import com.android.tools.r8.shaking.ProguardKeepRule;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

/** Tests -renamesourcefileattribute. */
@RunWith(Parameterized.class)
public class RenameSourceFileDebugTest extends DebugTestBase {

  private static final String TEST_FILE = "TestFile.java";

  private static Map<Backend, DebugTestConfig> configs = new HashMap<>();

  @BeforeClass
  public static void initDebuggeePath() throws Exception {
    for (Backend backend : ToolHelper.getBackends()) {
      Path outdir = temp.newFolder().toPath();
      Path outjar = outdir.resolve("r8_compiled.jar");
      Path proguardMapPath = outdir.resolve("proguard.map");
      R8Command.Builder builder =
          ToolHelper.addProguardConfigurationConsumer(
                  R8Command.builder(),
                  pgConfig -> {
                    pgConfig.addRule(ProguardKeepRule.defaultKeepAllRule(unused -> {}));
                    pgConfig.setRenameSourceFileAttribute(TEST_FILE);
                    pgConfig.addKeepAttributePatterns(
                        ImmutableList.of("SourceFile", "LineNumberTable"));
                  })
              .addProgramFiles(DEBUGGEE_JAR)
              .addProgramFiles(ToolHelper.getClassFileForTestClass(ClassInitializerEmpty.class))
              .setMode(CompilationMode.DEBUG)
              .setProguardMapOutputPath(proguardMapPath);
      DebugTestConfig config;
      if (backend == Backend.DEX) {
        AndroidApiLevel minSdk = ToolHelper.getMinApiLevelForDexVm();
        builder
            .setMinApiLevel(minSdk.getLevel())
            .addLibraryFiles(ToolHelper.getAndroidJar(minSdk))
            .setOutput(outjar, OutputMode.DexIndexed);
        config = new DexDebugTestConfig(outjar);
      } else {
        assert backend == Backend.CF;
        builder
            .addLibraryFiles(ToolHelper.getJava8RuntimeJar())
            .setOutput(outjar, OutputMode.ClassFile);
        config = new CfDebugTestConfig(outjar);
      }
      ToolHelper.runR8(builder.build());
      config.setProguardMap(proguardMapPath, MISSING_FILE_IS_EMPTY_MAP);
      configs.put(backend, config);
    }
  }

  private Backend backend;

  @Parameterized.Parameters(name = "Backend: {0}")
  public static Backend[] data() {
    return ToolHelper.getBackends();
  }

  public RenameSourceFileDebugTest(Backend backend) {
    this.backend = backend;
  }

  /** replica of {@link ClassInitializationTest#testBreakpointInEmptyClassInitializer} */
  @Test
  public void testBreakpointInEmptyClassInitializer() throws Throwable {
    final String CLASS = typeName(ClassInitializerEmpty.class);
    runDebugTest(
        configs.get(backend),
        CLASS,
        breakpoint(CLASS, "<clinit>"),
        run(),
        checkLine(TEST_FILE, 9),
        run());
  }

  /**
   * replica of {@link com.android.tools.r8.debug.LocalsTest#testNoLocal}, except for checking
   * overwritten class file.
   */
  @Test
  public void testNoLocal() throws Throwable {
    final String className = "Locals";
    final String methodName = "noLocals";
    runDebugTest(
        configs.get(backend),
        className,
        breakpoint(className, methodName),
        run(),
        checkMethod(className, methodName),
        checkLine(TEST_FILE, 8),
        checkNoLocal(),
        stepOver(),
        checkMethod(className, methodName),
        checkLine(TEST_FILE, 9),
        checkNoLocal(),
        run());
  }

  /** replica of {@link com.android.tools.r8.debug.MultipleReturnsTest#testMultipleReturns} */
  @Test
  public void testMultipleReturns() throws Throwable {
    runDebugTest(
        configs.get(backend),
        "MultipleReturns",
        breakpoint("MultipleReturns", "multipleReturns"),
        run(),
        stepOver(),
        checkLine(TEST_FILE, 16), // this should be the 1st return statement
        run(),
        stepOver(),
        checkLine(TEST_FILE, 18), // this should be the 2nd return statement
        run());
  }
}
