// 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, expectedName));
  }

  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));
  }
}
