// 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.shaking;

public class ProguardPackageMatcher {
  private final String pattern;

  public ProguardPackageMatcher(String pattern) {
    this.pattern = pattern;
  }

  public boolean matches(String packageName) {
    return matchPackageNameImpl(pattern, 0, packageName, 0);
  }

  @SuppressWarnings("UnnecessaryParentheses")
  private static boolean matchPackageNameImpl(
      String pattern, int patternIndex, String name, int nameIndex) {
    for (int i = patternIndex; i < pattern.length(); i++) {
      char patternChar = pattern.charAt(i);
      switch (patternChar) {
        case '*':
          int nextPatternIndex = i + 1;
          // Check for **.
          boolean includeSeparators =
              pattern.length() > (nextPatternIndex) && pattern.charAt(nextPatternIndex) == '*';
          if (includeSeparators) {
            nextPatternIndex += 1;
          }

          // Fast cases for the common case where a pattern ends with '*' or '**'.
          if (nextPatternIndex == pattern.length()) {
            if (includeSeparators) {
              return true;
            }
            boolean hasSeparators = containsSeparatorsStartingAt(name, nameIndex);
            return !hasSeparators;
          }

          // Match the rest of the pattern against the (non-empty) rest of the class name.
          for (int nextNameIndex = nameIndex; nextNameIndex < name.length(); nextNameIndex++) {
            if (!includeSeparators) {
              // Stop at the first separator for just *.
              if (name.charAt(nextNameIndex) == '.') {
                return matchPackageNameImpl(pattern, nextPatternIndex, name, nextNameIndex);
              }
            }
            if (matchPackageNameImpl(pattern, nextPatternIndex, name, nextNameIndex)) {
              return true;
            }
          }

          // Finally, check the case where the '*' or '**' eats all of the package name.
          return matchPackageNameImpl(pattern, nextPatternIndex, name, name.length());

        case '?':
          if (nameIndex == name.length() || name.charAt(nameIndex) == '.') {
            return false;
          }
          nameIndex++;
          break;

        default:
          if (nameIndex == name.length() || patternChar != name.charAt(nameIndex++)) {
            return false;
          }
          break;
      }
    }
    return nameIndex == name.length();
  }

  private static boolean containsSeparatorsStartingAt(String className, int nameIndex) {
    return className.indexOf('.', nameIndex) != -1;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof ProguardPackageMatcher)) {
      return false;
    }
    ProguardPackageMatcher other = (ProguardPackageMatcher) o;
    return pattern.equals(other.pattern);
  }

  @Override
  public int hashCode() {
    return pattern.hashCode();
  }
}
