// 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.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)
              .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
   * com.android.tools.r8.debug.ClassInitializationTest#testBreakpointInEmptyClassInitializer}
   */
  @Test
  public void testBreakpointInEmptyClassInitializer() throws Throwable {
    final String CLASS = "ClassInitializerEmpty";
    runDebugTest(
        configs.get(backend),
        CLASS,
        breakpoint(CLASS, "<clinit>"),
        run(),
        checkLine(TEST_FILE, 8),
        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());
  }
}
