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

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