// Copyright (c) 2019, 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.retrace;

import static com.android.tools.r8.retrace.internal.StackTraceRegularExpressionParser.DEFAULT_REGULAR_EXPRESSION;
import static junit.framework.TestCase.assertEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessagesImpl;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.retrace.stacktraces.InlineFileNameStackTrace;
import com.android.tools.r8.retrace.stacktraces.RetraceAssertionErrorStackTrace;
import com.android.tools.r8.retrace.stacktraces.StackTraceForTest;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.util.Collections;
import java.util.List;
import org.junit.Ignore;
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 StackTraceRegularExpressionParserTests extends TestBase {

  @Parameters(name = "{0}, verbose: {1}")
  public static List<Object[]> data() {
    return buildParameters(getTestParameters().withNoneRuntime().build(), BooleanUtils.values());
  }

  private final boolean verbose;

  public StackTraceRegularExpressionParserTests(TestParameters parameters, boolean verbose) {
    parameters.assertNoneRuntime();
    this.verbose = verbose;
  }

  @Test
  public void ensureNotMatchingOnLiteral() {
    runRetraceTest(
        "foo\\%c",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("foocom.android.tools.r8.a");
          }

          @Override
          public String mapping() {
            return "com.android.tools.r8.R8 -> com.android.tools.r8.a:";
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("foocom.android.tools.r8.a");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("foocom.android.tools.r8.a");
          }

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

  @Test
  public void matchMultipleTypeNamesOnLine() {
    // TODO(b/171691292): We are not supporting having multiple class matches for.
    runRetraceTest(
        "%c\\s%c\\s%c",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.a.a b.b.b c.c.c");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "AA.AA.AA -> a.a.a:", "BB.BB.BB -> b.b.b:", "CC.CC.CC -> c.c.c:");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("AA.AA.AA b.b.b c.c.c");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("AA.AA.AA b.b.b c.c.c");
          }

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

  @Test
  public void matchMultipleSlashNamesOnLine() {
    // TODO(b/171691292): We are not supporting having multiple class matches for.
    runRetraceTest(
        "%C\\s%C\\s%C",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a/a/a b/b/b c/c/c");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("AA.AA -> a.a.a:", "BB.BB -> b.b.b:", "CC.CC -> c.c.c:");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("AA/AA b/b/b c/c/c");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("AA/AA b/b/b c/c/c");
          }

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

  @Test
  public void matchMethodNameInNoContext() {
    runRetraceTest(
        "a.b.c.%m",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("com.android.tools.r8.R8 -> a.b.c:", "  void foo() -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

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

  @Test
  public void matchMethodNameInContext() {
    runRetraceTest(
        "%c.%m",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("com.android.tools.r8.R8 -> a.b.c:", "  void foo() -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.foo");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.void foo()");
          }

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

  @Test
  public void matchUnknownMethodNameInContext() {
    runRetraceTest(
        "%c.%m",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("com.android.tools.r8.R8 -> a.b.c:", "  void foo() -> b");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.a");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.a");
          }

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

  @Test
  public void matchQualifiedMethodInTrace() {
    runRetraceTest(DEFAULT_REGULAR_EXPRESSION, new InlineFileNameStackTrace());
  }

  @Test
  public void matchFieldNameInNoContext() {
    runRetraceTest(
        "a.b.c.%f",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("com.android.tools.r8.R8 -> a.b.c:", "  int foo -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

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

  @Test
  public void matchFieldNameInContext() {
    runRetraceTest(
        "%c.%f",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("com.android.tools.r8.R8 -> a.b.c:", "  int foo -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.foo");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.int foo");
          }

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

  @Test
  public void matchUnknownFieldNameInContext() {
    runRetraceTest(
        "%c.%f",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("com.android.tools.r8.R8 -> a.b.c:", "  boolean foo -> b");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.a");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.a");
          }

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

  @Test
  public void matchQualifiedFieldInTrace() {
    runRetraceTest(
        "%c\\.%f\\(%s\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return Collections.singletonList("a.b.c.d(Main.dummy)");
          }

          @Override
          public List<String> retracedStackTrace() {
            return Collections.singletonList("foo.Bar$Baz.baz(Bar.java)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return Collections.singletonList("foo.Bar$Baz.int baz(Bar.java)");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.naming.retrace.Main -> a.b.c:",
                "    int foo.Bar$Baz.baz -> d");
          }

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

  @Test
  public void matchSourceFileInContext() {
    runRetraceTest(
        "%c\\(%s\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c(SourceFile)");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("com.android.tools.r8.R8 -> a.b.c:", "  boolean foo -> b");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8(R8.java)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8(R8.java)");
          }

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

  @Test
  public void matchSourceFileInNoContext() {
    runRetraceTest(
        "%c\\(%s\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.d(SourceFile)");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("com.android.tools.r8.R8 -> a.b.c:", "  boolean foo -> b");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("a.b.d(SourceFile)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("a.b.d(SourceFile)");
          }

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

  @Test
  public void testLineNumberInMethodContext() {
    runRetraceTest(
        "%c\\.%m\\(%l\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a(3)");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.R8 -> a.b.c:", "  3:3:boolean foo():7 -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.foo(7)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.boolean foo()(7)");
          }

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

  @Test
  public void testNoLineNumberInMethodContext() {
    runRetraceTest(
        "%c\\.%m\\(%l\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a()");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.R8 -> a.b.c:", "  3:3:boolean foo():7 -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.foo(7)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.boolean foo()(7)");
          }

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

  @Test
  public void testNotFoundLineNumberInMethodContext() {
    runRetraceTest(
        "%c\\.%m\\(%l\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a(42)");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.R8 -> a.b.c:", "  3:3:boolean foo():7 -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.a(42)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.a(42)");
          }

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

  @Test
  public void testNotFoundLineNumberInNoLineNumberMappingMethodContext() {
    runRetraceTest(
        "%c\\.%m\\(%l\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a(4)");
          }

          @Override
          public String mapping() {
            return StringUtils.lines("com.android.tools.r8.R8 -> a.b.c:", "  boolean foo() -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.foo(4)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.boolean foo()(4)");
          }

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

  @Test
  public void testPruningByLineNumber() {
    runRetraceTest(
        "%c\\.%m\\(%l\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a(3)");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.R8 -> a.b.c:",
                "  3:3:boolean foo():7 -> a",
                "  4:4:boolean bar(int):8 -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.foo(7)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.boolean foo()(7)");
          }

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

  @Test
  public void matchOnType() {
    runRetraceTest(
        "%t",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("void", "a.a.a[]", "a.a.a[][][]");
          }

          @Override
          public String mapping() {
            return "";
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("void", "a.a.a[]", "a.a.a[][][]");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("void", "a.a.a[]", "a.a.a[][][]");
          }

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

  @Test
  public void matchOnFieldOrReturnType() {
    runRetraceTest(
        "%t %c.%m",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("void a.b.c.a", "a.a.a[] a.b.c.b");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.D8 -> a.a.a:",
                "com.android.tools.r8.R8 -> a.b.c:",
                "  void foo() -> a",
                "  com.android.tools.r8.D8[] bar() -> b");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of(
                "void com.android.tools.r8.R8.foo",
                "com.android.tools.r8.D8[] com.android.tools.r8.R8.bar");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            // TODO(b/199919195): Consider not writing full method description.
            return ImmutableList.of(
                "void com.android.tools.r8.R8.void foo()",
                "com.android.tools.r8.D8[] com.android.tools.r8.R8.com.android.tools.r8.D8[]"
                    + " bar()");
          }

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

  @Test()
  public void testSourceFileBeforeClassStackTrace() {
    runRetraceTest(
        "\\S* \\(%s: 70\\) %c.%m",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return Collections.singletonList(
                "0xffffffffffffffff (some-bundle.aab-canary-42: 70) ii2.p");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.naming.retrace.Main -> ii2:", "  void test() -> p");
          }

          @Override
          public List<String> retracedStackTrace() {
            return Collections.singletonList(
                "0xffffffffffffffff (Main.java: 70)"
                    + " com.android.tools.r8.naming.retrace.Main.test");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return Collections.singletonList(
                "0xffffffffffffffff (Main.java: 70)"
                    + " com.android.tools.r8.naming.retrace.Main.void test()");
          }

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

  @Test
  @Ignore("b/165782924")
  public void useReturnTypeToNarrowMethodMatches() {
    runRetraceTest(
        "%t %c.%m",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("void a.b.c.a", "a.a.a[] a.b.c.b");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.D8 -> a.a.a:",
                "com.android.tools.r8.R8 -> a.b.c:",
                "  void foo() -> a",
                "  int foo(int) -> a",
                "  com.android.tools.r8.D8[] bar() -> b",
                "  com.android.tools.r8.D8 bar(int) -> b");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of(
                "void com.android.tools.r8.R8.foo",
                "com.android.tools.r8.D8[] com.android.tools.r8.R8.bar");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of(
                "void com.android.tools.r8.R8.foo",
                "com.android.tools.r8.D8[] com.android.tools.r8.R8.bar");
          }

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

  @Test
  public void returnTypeCanMatchVoid() {
    runRetraceTest(
        "%t",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("void");
          }

          @Override
          public String mapping() {
            return "";
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("void");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("void");
          }

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

  @Test
  public void testArguments() {
    runRetraceTest(
        "%c.%m\\(%a\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a(int,a.a.a[],boolean)");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.D8 -> a.a.a:",
                "com.android.tools.r8.R8 -> a.b.c:",
                "  void foo(int,com.android.tools.r8.D8[],boolean) -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of(
                "com.android.tools.r8.R8.foo(int,com.android.tools.r8.D8[],boolean)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of(
                "com.android.tools.r8.R8.void foo(int,com.android.tools.r8.D8[],boolean)"
                    + "(int,com.android.tools.r8.D8[],boolean)");
          }

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

  @Test
  public void testNoArguments() {
    runRetraceTest(
        "%c.%m\\(%a\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a()");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.D8 -> a.a.a:",
                "com.android.tools.r8.R8 -> a.b.c:",
                "  void foo() -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.foo()");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.void foo()()");
          }

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

  @Test
  @Ignore("b/165782924")
  public void testPruningOfMethodsByFormals() {
    runRetraceTest(
        "%c.%m\\(%a\\)",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("a.b.c.a(a.a.a)");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "com.android.tools.r8.D8 -> a.a.a:",
                "com.android.tools.r8.R8 -> a.b.c:",
                "  void foo() -> a",
                "  void bar(com.android.tools.r8.D8) -> a");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.bar(com.android.tools.r8.D8)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("com.android.tools.r8.R8.bar(com.android.tools.r8.D8)");
          }

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

  @Test
  public void matchOnSimpleStackTrace() {
    runRetraceTest(
        DEFAULT_REGULAR_EXPRESSION,
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of(
                "com.android.tools.r8.a: foo bar baz",
                "  at com.android.tools.r8.b.a(SourceFile)",
                "  at a.c.a.b(SourceFile)");
          }

          @Override
          public String mapping() {
            return StringUtils.joinLines(
                "com.android.tools.r8.R8 -> com.android.tools.r8.a:",
                "com.android.tools.r8.Bar -> com.android.tools.r8.b:",
                "  void foo() -> a",
                "com.android.tools.r8.Baz -> a.c.a:",
                "  void bar() -> b");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of(
                "com.android.tools.r8.R8: foo bar baz",
                "  at com.android.tools.r8.Bar.foo(Bar.java)",
                "  at com.android.tools.r8.Baz.bar(Baz.java)");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of(
                "com.android.tools.r8.R8: foo bar baz",
                "  at com.android.tools.r8.Bar.void foo()(Bar.java)",
                "  at com.android.tools.r8.Baz.void bar()(Baz.java)");
          }

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

  @Test
  public void testSourceFileLineNumber() {
    runRetraceTest(
        DEFAULT_REGULAR_EXPRESSION.replace("%s(?::%l)?", "%S"),
        new RetraceAssertionErrorStackTrace());
  }

  @Test
  public void testEscaping() {
    runRetraceTest(
        "\\%c\\\\%c\\\\\\%c.%m\\(\\\\%S\\)\\\\\\%S",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of("%c\\com.android.tools.r8.Foo\\%c.a(\\SourceFile:1)\\%S");
          }

          @Override
          public String mapping() {
            return "com.android.tools.r8.Bar -> com.android.tools.r8.Foo:\n"
                + "  1:1:void m():13:13 -> a";
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of("%c\\com.android.tools.r8.Bar\\%c.m(\\Bar.java:13)\\%S");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of("%c\\com.android.tools.r8.Bar\\%c.void m()(\\Bar.java:13)\\%S");
          }

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

  /* This is a regression test for b/216359244 */
  @Test
  public void testMissingSourceFile() {
    runRetraceTest(
        ".*FOO\\s+:\\s+\\[\\d+\\]\\s+%c\\.%m\\(%l\\):.*",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of(
                "12-24 19:53:19.052 10197 30302 30302 I FOO : [2] huk.g(1): getDownloads()");
          }

          @Override
          public String mapping() {
            return "foo.Bar -> huk:\n" + "  void baz():13:13 -> g\n" + "  void qux():12:12 -> g\n";
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of(
                "12-24 19:53:19.052 10197 30302 30302 I FOO : [2] foo.Bar.baz(13): getDownloads()",
                "<OR> 12-24 19:53:19.052 10197 30302 30302 I FOO : [2] foo.Bar.qux(12):"
                    + " getDownloads()");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of(
                "12-24 19:53:19.052 10197 30302 30302 I FOO : [2] foo.Bar.void baz()(13):"
                    + " getDownloads()",
                "<OR> 12-24 19:53:19.052 10197 30302 30302 I FOO : [2] foo.Bar.void qux()(12):"
                    + " getDownloads()");
          }

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

  @Test
  public void testBigLine() {
    runRetraceTest(
        RetraceOptions.defaultRegularExpression(),
        new StackTraceForTest() {

          private final String LINE =
              "12-16 19:29:11.111 media 453 490 D WVCdm : [for_bar.cpp(334):AddKey] key_data ="
                  + " (1401)"
                  + " CAISvgYKmgIKIEIzMkU1QkU3RjlGMThCNzYzQjAwMDAwMDAwMDAwMDAwEuMBeyJ2ZXJzaW9uIjoiM"
                  + "S4wIiwiZXNuIjoiTkZBTkRST0lEMi1QUlYtQk9SRUFMLUdPT0dMQ0hST01FQ0FTVD1IRC0yMTc5My0"
                  + "1Nzk0RDMyRTQxRUI5QTc2QzZFQzIyNTdEQzVGNTQ2MTNDNzdBQTdCNzAwNzcyMkREQjVCRDYzRUFER"
                  + "TZBRUUyIiwic2FsdCI6IjQ5OTI3MDU0ODMyNzI0NjIxMDc0MDM4Nzg3MDkxMjAyNCIsImlzc3VlVGl"
                  + "tZSI6MTYzOTY2MzE1MDAwMCwibW92aWVJZCI6IjgxMTg0NDE3In0gASgAOMDRAkDA0QJIroztjQYSF"
                  + "AgBEAAYACDA0QIowNECWABgAXgBGmYSEBnHXFI_ttc_1lja-bpjqHkaUN_81aKusLLERz_xX0vPIR1"
                  + "I8yu9u9zQndpy1aEFJYtQiB0sed6wAC3c6aeH4oLsGFPiuVgGweP1MGc3yxunqusDpoGe03JGD1VSE"
                  + "9aB0jSKIAEahgEKEAAAAAAGmcHCAAAAAAAAAAASEN4b9_2XH75TnxdBkpJ4YhoaIOdhQxec7DpUs0D"
                  + "ixSQXTlvjbXqX3PIOg9DiQLCa4vbzIAIoBToECAEQKkI0CiDuiCOCIxvTlCqkYTKBWzMOfeh9BpKc5"
                  + "RDdE2omMbOfaRIQRWVqtbR8Qg4JEY0u0CAFRBqGAQoQAAAAAAaZwcMAAAAAAAAAABIQ7iP9449yr2F"
                  + "_97v4QHerRxognKGBtw2cwGpxKltxU7A_1asVTS0aPaw8dr5e2rP2SW4gAigFOgQIARAqQjQKIB-50"
                  + "Ou_RGn8rzRDr76FeWpBLYSt99zHVSZK0xnd_anREhC4eACukLOUwL5TQ8w1oOAVGoYBChAAAAAABpn"
                  + "BwQAAAAAAAAAAEhDsGE2bR6VgRM85PY3YU9qIGiAhD3h7I8Cv5Irr315yecWo0YA1t9_sr0g2z0zsa"
                  + "6Dq0yACKAE6BAgBECpCNAogQoIDcKUGMhCA-HetsARASXxXJUazkIIaSwCKE9asAEwSEMW4TIMZZkc"
                  + "r3LYIITelMlIgroztjQY4ABogzw-SGqQ1AYy8EopI2zSvXX_hkFpOoWxCvFQuQEj5oQwigAIRzNhvB"
                  + "9-YMOy2Muentb574WJKnVqXfEor5mFDIQ3vDELdjbkibaS4THyK2DlUQyp0M3C8n5bQ1JApslsfh5w"
                  + "SEMvA8Y0sXE9H6xnAKnMJTioZJOTElqPrbbRM5APhI3ohL8rp7u8ydBm9aWqkprDngrU3b1KdHd6J9"
                  + "YiJRJ4Y55M4qqCdwbCqr57xYAu_IIH_p8erfnhfNgUE2svtZBiLMP37vOMSQAP08_zkMf87VRHBxuI"
                  + "2rlnGcdgLoJyPgLp2ZBbdLw-b4Nq6uIZQfNABQ1SuM3OZ6uD6eq-NH9FawWvN0EmzWZ88DGiHtgM7h"
                  + "zqvIb8JNmLInt28us-vw6KQOggKBjE2LjUuMEABSoACAAAAAgAAAQAABAAQZrvQTwAAABMAAAE3AAA"
                  + "AEAAAAUkAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAKjAA"
                  + "AAAAAAAqMAAAAAAAAAAAAAAAAMAAAGgAAAAEAAAAbIAAAAQAAABxAAAABAAAAIUAAAAEAAAAfIAAAA"
                  + "gAAACKQAAABAAAAI7AAAAEAAAAk0AAAAQAAACnQAAABAAAAJ7AAAAIAAAArIAAAAQAAACxAAAABAAA"
                  + "ALWAAAAEAAAAyYAAAAQAAADBAAAACC8nuR7W9i8AuG9xF3K__n1kk9F_G1i25QRKR9YXyssdsadWT";

          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of(LINE);
          }

          @Override
          public String mapping() {
            return "foo.Bar -> huk:\n" + "  void baz():13:13 -> g\n" + "  void qux():12:12 -> g\n";
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of(LINE);
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of(LINE);
          }

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

  /* This is a regression test for b/222749348 */
  @Test
  public void testGroups() {
    runRetraceTest(
        "(?:(?:.*?%c %m\\(%s(?:: %l)?\\)))",
        new StackTraceForTest() {
          @Override
          public List<String> obfuscatedStackTrace() {
            return ImmutableList.of(
                "FOO bar(PG: 1)",
                "FOO bar(PG : 1)",
                "FOO bar(PG:1)",
                "FOO bar(PG:1 )",
                "FOO bar(PG: 1 )");
          }

          @Override
          public String mapping() {
            return StringUtils.lines(
                "this.was.Deobfuscated -> FOO:",
                "    int[] mFontFamily -> a",
                "    1:3:void someMethod(int):65:67 -> bar");
          }

          @Override
          public List<String> retracedStackTrace() {
            return ImmutableList.of(
                "this.was.Deobfuscated someMethod(Deobfuscated.java: 65)",
                "this.was.Deobfuscated someMethod(Deobfuscated.java: 65)",
                "FOO bar(PG:1)",
                "FOO bar(PG:1 )",
                "FOO bar(PG: 1 )");
          }

          @Override
          public List<String> retraceVerboseStackTrace() {
            return ImmutableList.of(
                "this.was.Deobfuscated void someMethod(int)(Deobfuscated.java: 65)",
                "this.was.Deobfuscated void someMethod(int)(Deobfuscated.java: 65)",
                "FOO bar(PG:1)",
                "FOO bar(PG:1 )",
                "FOO bar(PG: 1 )");
          }

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

  private TestDiagnosticMessagesImpl runRetraceTest(
      String regularExpression, StackTraceForTest stackTraceForTest) {
    TestDiagnosticMessagesImpl diagnosticsHandler = new TestDiagnosticMessagesImpl();
    RetraceCommand retraceCommand =
        RetraceCommand.builder(diagnosticsHandler)
            .setProguardMapProducer(ProguardMapProducer.fromString(stackTraceForTest.mapping()))
            .setStackTrace(stackTraceForTest.obfuscatedStackTrace())
            .setRetracedStackTraceConsumer(
                retraced -> {
                  assertEquals(
                      verbose
                          ? stackTraceForTest.retraceVerboseStackTrace()
                          : stackTraceForTest.retracedStackTrace(),
                      retraced);
                })
            .setRegularExpression(regularExpression)
            .setVerbose(verbose)
            .build();
    Retrace.run(retraceCommand);
    return diagnosticsHandler;
  }
}
