// Copyright (c) 2020, 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.utils.codeinspector.Matchers.containsLinePositions;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static junit.framework.TestCase.assertEquals;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.R8TestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.naming.retrace.StackTrace;
import com.android.tools.r8.naming.testclasses.ClassToBeMinified;
import com.android.tools.r8.naming.testclasses.Main;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.shaking.ProguardKeepAttributes;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.Matchers.LinePosition;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
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 RenameSourceFileRetraceTest extends TestBase {

  private static final String FILENAME_RENAME = "FOO";
  private static final String FILENAME_MAIN = "Main.java";
  private static final String FILENAME_CLASS_TO_BE_MINIFIED = "ClassToBeMinified.java";

  private final TestParameters parameters;
  private final boolean isCompat;
  private final boolean keepSourceFile;

  @Parameters(name = "{0}, is compat: {1}, keep source file attribute: {2}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().build(),
        BooleanUtils.values(),
        BooleanUtils.values());
  }

  public RenameSourceFileRetraceTest(
      TestParameters parameters, Boolean isCompat, Boolean keepSourceFile) {
    this.parameters = parameters;
    this.isCompat = isCompat;
    this.keepSourceFile = keepSourceFile;
  }

  @Test
  public void testR8()
      throws ExecutionException, CompilationFailedException, IOException, NoSuchMethodException {
    R8TestBuilder<? extends R8TestBuilder<?>> r8TestBuilder =
        isCompat ? testForR8Compat(parameters.getBackend()) : testForR8(parameters.getBackend());
    if (keepSourceFile) {
      r8TestBuilder.addKeepAttributes(ProguardKeepAttributes.SOURCE_FILE);
    }
    String minifiedFileName =
        (keepSourceFile && isCompat) ? FILENAME_CLASS_TO_BE_MINIFIED : getDefaultExpectedName();
    String mainFileName = keepSourceFile ? FILENAME_MAIN : getDefaultExpectedName();
    r8TestBuilder
        .addProgramClasses(ClassToBeMinified.class, Main.class)
        .addKeepAttributes(ProguardKeepAttributes.LINE_NUMBER_TABLE)
        .addKeepMainRule(Main.class)
        .setMinApi(parameters.getApiLevel())
        .enableInliningAnnotations()
        .run(parameters.getRuntime(), Main.class)
        .assertFailureWithErrorThatMatches(containsString("ClassToBeMinified.foo()"))
        .inspectFailure(inspector -> inspectOutput(inspector, minifiedFileName, mainFileName))
        .inspectStackTrace(stackTrace -> inspectStackTrace(stackTrace, FILENAME_MAIN));
  }

  @Test
  public void testRenameSourceFileR8()
      throws ExecutionException, CompilationFailedException, IOException, NoSuchMethodException {
    R8TestBuilder<? extends R8TestBuilder<?>> r8TestBuilder =
        isCompat ? testForR8Compat(parameters.getBackend()) : testForR8(parameters.getBackend());
    if (keepSourceFile) {
      r8TestBuilder.addKeepAttributes(ProguardKeepAttributes.SOURCE_FILE);
    }
    String expectedName = getDefaultExpectedName(FILENAME_RENAME);
    r8TestBuilder
        .addProgramClasses(ClassToBeMinified.class, Main.class)
        .addKeepAttributes(ProguardKeepAttributes.LINE_NUMBER_TABLE)
        .addKeepRules("-renamesourcefileattribute " + FILENAME_RENAME)
        .addKeepMainRule(Main.class)
        .setMinApi(parameters.getApiLevel())
        .enableInliningAnnotations()
        .run(parameters.getRuntime(), Main.class)
        .assertFailureWithErrorThatMatches(containsString("ClassToBeMinified.foo()"))
        .inspectFailure(inspector -> inspectOutput(inspector, expectedName, expectedName))
        .inspectStackTrace(stackTrace -> inspectStackTrace(stackTrace, FILENAME_MAIN));
  }

  private String getDefaultExpectedName() {
    return getDefaultExpectedName(parameters.getBackend() == Backend.CF ? "SourceFile" : "");
  }

  private String getDefaultExpectedName(String name) {
    if (!keepSourceFile) {
      if (parameters.getBackend() == Backend.CF || !isCompat) {
        return null;
      }
    }
    return name;
  }

  private void inspectOutput(
      CodeInspector inspector, String classToBeMinifiedFilename, String mainClassFilename) {
    inspectSourceFileForClass(inspector, Main.class, mainClassFilename);
    inspectSourceFileForClass(inspector, ClassToBeMinified.class, classToBeMinifiedFilename);
  }

  private void inspectSourceFileForClass(CodeInspector inspector, Class<?> clazz, String expected) {
    ClassSubject classToBeMinifiedSubject = inspector.clazz(clazz);
    assertThat(classToBeMinifiedSubject, isPresent());
    DexClass dexClass = classToBeMinifiedSubject.getDexProgramClass();
    String actualString = dexClass.sourceFile == null ? null : dexClass.sourceFile.toString();
    assertEquals(expected, actualString);
  }

  private void inspectStackTrace(StackTrace stackTrace, String mainFileName)
      throws NoSuchMethodException {
    if (!keepSourceFile) {
      return;
    }
    assertEquals(2, stackTrace.getStackTraceLines().size());
    MethodReference classToBeMinifiedFoo =
        Reference.methodFromMethod(ClassToBeMinified.class.getDeclaredMethod("foo"));
    MethodReference mainMain =
        Reference.methodFromMethod(Main.class.getDeclaredMethod("main", String[].class));
    LinePosition expectedStack =
        LinePosition.stack(
            LinePosition.create(classToBeMinifiedFoo, 1, 13, FILENAME_CLASS_TO_BE_MINIFIED),
            LinePosition.create(mainMain, 1, 10, mainFileName));
    assertThat(stackTrace, containsLinePositions(expectedStack));
  }
}
