// 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.internal.retrace;

import static com.android.tools.r8.retrace.internal.StackTraceRegularExpressionParser.DEFAULT_REGULAR_EXPRESSION;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessagesImpl;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.internal.retrace.stacktraces.CronetStackTrace;
import com.android.tools.r8.internal.retrace.stacktraces.FinskyStackTrace;
import com.android.tools.r8.internal.retrace.stacktraces.VelvetStackTrace;
import com.android.tools.r8.retrace.ProguardMapProducer;
import com.android.tools.r8.retrace.Retrace;
import com.android.tools.r8.retrace.RetraceCommand;
import com.android.tools.r8.retrace.stacktraces.StackTraceForTest;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import junit.framework.TestCase;
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 RetraceTests extends TestBase {

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withNoneRuntime().build();
  }

  private static String REMAPPER_REGEX =
      "(?:.*?\\bat\\s+%c\\.%m\\s*\\(%S\\)\\s*)"
          + "|(?:(?:.*?[:\"]\\s+)?%c(?::.*)?)"
          + "|(?:.*?%t\\s+%c\\.%m\\s*\\(%a\\)\\s*)";
  private static String FINSKY_REGEX = "(?:.*Finsky\\s+:\\s+\\[\\d+\\]\\s+%c\\.%m\\(%l\\):.*)";
  private static String SMILEY_EMOJI = "\uD83D\uDE00";

  public RetraceTests(TestParameters parameters) {
    parameters.assertNoneRuntime();
  }

  @Test
  public void testCronetStackTrace() {
    runRetraceTest(new CronetStackTrace());
  }

  @Test
  public void testFinskyStackTrace() {
    runRetraceTest(new FinskyStackTrace(), FINSKY_REGEX);
  }

  @Test
  public void testCronetRemapperRegexpTest() {
    runRetraceTest(new CronetStackTrace(), REMAPPER_REGEX);
  }

  @Test
  public void testCronetAndFinskyStackTrace() {
    CronetStackTrace cronetStackTrace = new CronetStackTrace();
    FinskyStackTrace finskyStackTrace = new FinskyStackTrace();
    runRetraceTest(
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            ArrayList<String> obfuscated = new ArrayList<>();
            obfuscated.addAll(cronetStackTrace.obfuscatedStackTrace());
            obfuscated.addAll(finskyStackTrace.obfuscatedStackTrace());
            return obfuscated;
          }

          @Override
          public String mapping() {
            return cronetStackTrace.mapping();
          }

          @Override
          public List<String> retracedStackTrace() {
            ArrayList<String> retraced = new ArrayList<>();
            retraced.addAll(cronetStackTrace.retracedStackTrace());
            retraced.addAll(finskyStackTrace.retracedStackTrace());
            return retraced;
          }

          @Override
          public int expectedWarnings() {
            return 0;
          }
        },
        FINSKY_REGEX + "|" + DEFAULT_REGULAR_EXPRESSION);
  }

  @Test
  public void testCronetAndFinskyStackTraceRemapperRegExp() {
    CronetStackTrace cronetStackTrace = new CronetStackTrace();
    FinskyStackTrace finskyStackTrace = new FinskyStackTrace();
    runRetraceTest(
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            ArrayList<String> obfuscated = new ArrayList<>();
            obfuscated.addAll(cronetStackTrace.obfuscatedStackTrace());
            obfuscated.addAll(finskyStackTrace.obfuscatedStackTrace());
            return obfuscated;
          }

          @Override
          public String mapping() {
            return cronetStackTrace.mapping();
          }

          @Override
          public List<String> retracedStackTrace() {
            ArrayList<String> retraced = new ArrayList<>();
            retraced.addAll(cronetStackTrace.retracedStackTrace());
            retraced.addAll(finskyStackTrace.retracedStackTrace());
            return retraced;
          }

          @Override
          public int expectedWarnings() {
            return 0;
          }
        },
        FINSKY_REGEX + "|" + REMAPPER_REGEX);
  }

  @Test
  public void testVelvetStackTrace() {
    runRetraceTest(new VelvetStackTrace());
  }

  @Test
  public void testNonAscii() {
    CronetStackTrace cronetStackTrace = new CronetStackTrace();
    runRetraceTest(
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            ArrayList<String> smileyObf = new ArrayList<>();
            smileyObf.add(SMILEY_EMOJI);
            smileyObf.addAll(cronetStackTrace.obfuscatedStackTrace());
            return smileyObf;
          }

          @Override
          public String mapping() {
            return cronetStackTrace.mapping();
          }

          @Override
          public List<String> retracedStackTrace() {
            ArrayList<String> smileyObf = new ArrayList<>();
            smileyObf.add(SMILEY_EMOJI);
            smileyObf.addAll(cronetStackTrace.retracedStackTrace());
            return smileyObf;
          }

          @Override
          public int expectedWarnings() {
            return 0;
          }
        });
  }

  private TestDiagnosticMessagesImpl runRetraceTest(StackTraceForTest stackTraceForTest) {
    return runRetraceTest(stackTraceForTest, DEFAULT_REGULAR_EXPRESSION);
  }

  private TestDiagnosticMessagesImpl runRetraceTest(
      StackTraceForTest stackTraceForTest, String regularExpression) {
    return runRetraceTest(stackTraceForTest, regularExpression, TestCase::assertEquals);
  }

  private TestDiagnosticMessagesImpl runRetraceTest(
      StackTraceForTest stackTraceForTest,
      String regularExpression,
      BiConsumer<List<String>, List<String>> matcher) {
    TestDiagnosticMessagesImpl diagnosticsHandler = new TestDiagnosticMessagesImpl();
    RetraceCommand retraceCommand =
        RetraceCommand.builder(diagnosticsHandler)
            .setProguardMapProducer(ProguardMapProducer.fromString(stackTraceForTest.mapping()))
            .setStackTrace(stackTraceForTest.obfuscatedStackTrace())
            .setRegularExpression(regularExpression)
            .setRetracedStackTraceConsumer(
                retraced -> matcher.accept(stackTraceForTest.retracedStackTrace(), retraced))
            .build();
    Retrace.run(retraceCommand);
    return diagnosticsHandler;
  }
}
