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

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.shaking.ProguardConfigurationParser.IdentifierPatternWithWildcards;
import com.android.tools.r8.shaking.ProguardTypeMatcher.ClassOrType;
import com.android.tools.r8.shaking.ProguardWildcard.BackReference;
import com.android.tools.r8.shaking.ProguardWildcard.Pattern;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;

public class ProguardNameMatchingTest {
  private static final String[] BASIC_TYPES = {
      "char", "byte", "short", "int", "long", "float", "double", "boolean"
  };

  private static final DexItemFactory dexItemFactory = new DexItemFactory();

  private static boolean matchTypeName(String typeName, String pattern) {
    return ProguardTypeMatcher.create(
        toIdentifierPatternWithWildCards(pattern, false), ClassOrType.TYPE, dexItemFactory)
        .matches(dexItemFactory.createType(DescriptorUtils.javaTypeToDescriptor(typeName)));
  }

  private static boolean matchClassName(String className, String... patterns) {
    return matchClassName(className, ImmutableList.of(Arrays.asList(patterns)));
  }

  private static boolean matchClassName(String className, List<List<String>> patternsList) {
    ProguardClassFilter.Builder builder = ProguardClassFilter.builder();
    for (List<String> patterns : patternsList) {
      ProguardClassNameList.Builder listBuilder = ProguardClassNameList.builder();
      for (String pattern : patterns) {
        boolean isNegated = pattern.startsWith("!");
        String actualPattern = isNegated ? pattern.substring(1) : pattern;
        listBuilder.addClassName(isNegated,
            ProguardTypeMatcher.create(
                toIdentifierPatternWithWildCards(actualPattern, false),
                ClassOrType.CLASS, dexItemFactory));
      }
      builder.addPattern(listBuilder.build());
    }
    return builder.build()
        .matches(dexItemFactory.createType(DescriptorUtils.javaTypeToDescriptor(className)));
  }

  private static boolean matchMemberName(String pattern, String memberName) {
    ProguardNameMatcher nameMatcher =
        ProguardNameMatcher.create(toIdentifierPatternWithWildCards(pattern, true));
    return nameMatcher.matches(memberName);
  }

  @Test
  public void matchClassNames() {
    assertTrue(matchClassName("", "**"));
    assertTrue(matchClassName("a", "**"));
    assertTrue(matchClassName("", "*"));
    assertTrue(matchClassName("a", "*"));
    assertFalse(matchClassName("", "?"));
    assertTrue(matchClassName("a", "?"));

    assertTrue(matchClassName("java.lang.Object", "**"));
    assertFalse(matchClassName("java.lang.Object", "ja*"));
    assertTrue(matchClassName("java.lang.Object", "ja**"));
    assertTrue(matchClassName("java.lang.Object", "ja**ject"));
    // Oddly, the proguard specification for this makes a lonely * synonymous with **.
    assertTrue(matchClassName("java.lang.Object", "*"));
    assertFalse(matchClassName("java.lang.Object", "ja*ject"));

    assertTrue(matchClassName("java.lang.Object", "java.*g.O*"));
    assertTrue(matchClassName("java.lang.Object", "java.*g.O?je?t"));
    assertTrue(matchClassName("java.lang.Object", "?ava.*g.Ob<1>e*"));
    assertTrue(matchClassName("java.lang.Object", "j?v<1>.*<1>*g.Obj*"));
    assertTrue(matchClassName("java.lang.Object", "j*v?.*<2>*g.Obj*"));
    assertFalse(matchClassName("java.lang.Object", "java.*g.O?je?t?"));
    assertFalse(matchClassName("java.lang.Object", "java?lang.Object"));
    assertTrue(matchClassName("java.lang.Object", "*a*.*a**"));
    assertTrue(matchClassName("java.lang.Object", "*a**a**"));
    assertTrue(matchClassName("java.lang.Object", "*?**<2>**"));

    assertTrue(matchClassName("java.lang.Object", "!java.util.**", "java**"));
    assertFalse(matchClassName("java.lang.Object", "!java.**", "java.lang.*"));
    assertTrue(matchClassName("java.lang.Object", "java.lang.*", "!java.**"));

    assertTrue(matchClassName("boobar", "!foobar", "*bar"));
    assertTrue(matchClassName("boobar", "!foobar", "?*<1>ar"));
    assertFalse(matchClassName("foobar", "!foobar", "*bar"));

    assertTrue(matchClassName("foo", "!boo"));
    assertTrue(matchClassName("foo", "baz", "!boo"));

    assertFalse(matchClassName("boo", "!boo", "**"));
    assertFalse(matchClassName("boo", "!b*<1>", "**"));
    assertFalse(matchClassName("boo", "!b?<1>", "**"));
    assertTrue(matchClassName("boo", "**", "!boo"));
    assertTrue(matchClassName("boo",
        ImmutableList.of(ImmutableList.of("!boo"), ImmutableList.of("**"))));

    assertFalse(matchClassName("boofoo", "!boo*", "*foo", "boofoo"));
    assertTrue(matchClassName("boofoo",
        ImmutableList.of(ImmutableList.of("!boo*,*foo"), ImmutableList.of("boofoo"))));
  }

  private void assertMatchesBasicTypes(String pattern) {
    for (String type : BASIC_TYPES) {
      assertTrue(matchTypeName(type, pattern));
    }
  }

  private void assertDoesNotMatchBasicTypes(String pattern) {
    for (String type : BASIC_TYPES) {
      assertFalse(matchTypeName(type, pattern));
    }
  }

  @Test
  public void matchTypeNames() {
    assertTrue(matchTypeName("java.lang.Object", "**"));
    assertDoesNotMatchBasicTypes("**");
    assertDoesNotMatchBasicTypes("*");
    assertFalse(
        matchTypeName("java.lang.Object[]", "**"));
    assertFalse(
        matchTypeName("java.lang.Object", "**z"));
    assertFalse(matchTypeName("java.lang.Object[]", "java.**"
    ));
    assertTrue(
        matchTypeName("java.lang.Object[]", "***"));
    assertTrue(matchTypeName("java.lang.Object[][]", "***"
    ));
    assertFalse(matchTypeName("java.lang.Object", "%"));
    assertTrue(matchTypeName("a", "**"));
    assertTrue(matchTypeName("java.lang.Object[]", "**[]"
    ));
    assertFalse(matchTypeName("java.lang.Object[][]", "**[]"
    ));
    assertTrue(matchTypeName("abc", "*"));
    assertMatchesBasicTypes("***");
    assertMatchesBasicTypes("%");
  }

  @Test
  public void matchFieldOrMethodNames() {
    assertTrue(matchMemberName("*", ""));
    assertTrue(matchMemberName("*", "get"));
    assertTrue(matchMemberName("get*", "get"));
    assertTrue(matchMemberName("get*", "getObject"));
    assertTrue(matchMemberName("*t", "get"));
    assertTrue(matchMemberName("g*t*", "getObject"));
    assertTrue(matchMemberName("g*t***************", "getObject"));
    assertFalse(matchMemberName("get*y", "getObject"));
    assertFalse(matchMemberName("getObject?", "getObject"));
    assertTrue(matchMemberName("getObject?", "getObject1"));
    assertTrue(matchMemberName("getObject?", "getObject5"));

    assertTrue(matchMemberName("ge?Objec<1>", "getObject"));
    assertTrue(matchMemberName("ge*Objec<1>", "getObject"));
    assertTrue(matchMemberName("ge*Objec<1>", "geObjec"));
    assertTrue(matchMemberName("g?*Obj<1>c<2>", "getObject"));
    assertTrue(matchMemberName("g??Obj<1>c<2>", "getObject"));
    assertTrue(matchMemberName("g*?Obj<1>c<2>", "getObject"));
    assertFalse(matchMemberName("g?*Obj<1>c<2>", "getObject1"));
    assertTrue(matchMemberName("g**Obj<1>c<2>", "getObject"));
    assertFalse(matchMemberName("g**Obj<1>c<2>", "getObject1"));
    assertTrue(matchMemberName("g?*Obj<1>c<2>?", "getObject1"));
    assertTrue(matchMemberName("g**Obj<1>c<2>?", "getObject1"));
    assertTrue(matchMemberName("*foo<1>", "foofoofoo"));
    assertTrue(matchMemberName("*foo<1>", "barfoobar"));
    assertFalse(matchMemberName("*foo<1>", "barfoobaz"));
  }

  private static IdentifierPatternWithWildcards toIdentifierPatternWithWildCards(
      String pattern, boolean isForNameMatcher) {
    ImmutableList.Builder<ProguardWildcard> builder = ImmutableList.builder();
    String allPattern = "";
    String backReference = "";
    for (int i = 0; i < pattern.length(); i++) {
      char patternChar = pattern.charAt(i);
      if (backReference.length() > 0) {
        if (patternChar == '>') {
          backReference += patternChar;
          builder.add(new BackReference(
              Integer.parseInt(backReference.substring(1, backReference.length() - 1))));
          backReference = "";
        } else {
          backReference += patternChar;
        }
        continue;
      } else if (allPattern.length() > 0) {
        if (patternChar == '*') {
          allPattern += patternChar;
          continue;
        } else {
          builder.add(new Pattern(allPattern));
          allPattern = "";
        }
      }

      if (patternChar == '*') {
        if (isForNameMatcher) {
          builder.add(new Pattern(String.valueOf(patternChar)));
        } else {
          allPattern += patternChar;
        }
      } else if (patternChar == '?' || patternChar == '%') {
        builder.add(new Pattern(String.valueOf(patternChar)));
      } else if (patternChar == '<') {
        backReference += patternChar;
      }
    }
    if (allPattern.length() > 0) {
      builder.add(new Pattern(allPattern));
    }
    List<ProguardWildcard> wildcards = builder.build();
    linkBackReferences(wildcards);
    return new IdentifierPatternWithWildcards(pattern, wildcards);
  }

  private static void linkBackReferences(Iterable<ProguardWildcard> wildcards) {
    List<Pattern> patterns = new ArrayList<>();
    for (ProguardWildcard wildcard : wildcards) {
      if (wildcard.isBackReference()) {
        BackReference backReference = wildcard.asBackReference();
        backReference.setReference(patterns.get(backReference.referenceIndex - 1));
      } else {
        assert wildcard.isPattern();
        patterns.add(wildcard.asPattern());
      }
    }
  }
}
