// 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 com.android.tools.r8.shaking.ProguardConfigurationParser.IdentifierPatternWithWildcards;
import com.android.tools.r8.shaking.ProguardWildcard.BackReference;
import com.android.tools.r8.shaking.ProguardWildcard.Pattern;
import com.google.common.collect.ImmutableList;
import java.util.Collections;
import java.util.List;

public abstract class ProguardNameMatcher {

  private static final ProguardNameMatcher MATCH_ALL_NAMES = new MatchAllNames();

  private ProguardNameMatcher() {
  }

  public static ProguardNameMatcher create(
      IdentifierPatternWithWildcards identifierPatternWithWildcards) {
    if (identifierPatternWithWildcards.isMatchAllNames()) {
      return MATCH_ALL_NAMES;
    } else if (identifierPatternWithWildcards.wildcards.isEmpty()) {
      return new MatchSpecificName(identifierPatternWithWildcards.pattern);
    } else {
      return new MatchNamePattern(identifierPatternWithWildcards);
    }
  }

  private static boolean matchFieldOrMethodNameImpl(
      String pattern, int patternIndex,
      String name, int nameIndex,
      List<ProguardWildcard> wildcards, int wildcardIndex) {
    ProguardWildcard wildcard;
    Pattern wildcardPattern;
    BackReference backReference;
    for (int i = patternIndex; i < pattern.length(); i++) {
      char patternChar = pattern.charAt(i);
      switch (patternChar) {
        case '*':
          wildcard = wildcards.get(wildcardIndex);
          assert wildcard.isPattern();
          wildcardPattern = wildcard.asPattern();
          // Match the rest of the pattern against the rest of the name.
          for (int nextNameIndex = nameIndex; nextNameIndex <= name.length(); nextNameIndex++) {
            wildcardPattern.setCaptured(name.substring(nameIndex, nextNameIndex));
            if (matchFieldOrMethodNameImpl(
                pattern, i + 1, name, nextNameIndex, wildcards, wildcardIndex + 1)) {
              return true;
            }
          }
          return false;
        case '?':
          wildcard = wildcards.get(wildcardIndex);
          assert wildcard.isPattern();
          if (nameIndex == name.length()) {
            return false;
          }
          wildcardPattern = wildcard.asPattern();
          wildcardPattern.setCaptured(name.substring(nameIndex, nameIndex + 1));
          nameIndex++;
          wildcardIndex++;
          break;
        case '<':
          wildcard = wildcards.get(wildcardIndex);
          assert wildcard.isBackReference();
          backReference = wildcard.asBackReference();
          String captured = backReference.getCaptured();
          if (captured == null
              || name.length() < nameIndex + captured.length()
              || !captured.equals(name.substring(nameIndex, nameIndex + captured.length()))) {
            return false;
          }
          nameIndex = nameIndex + captured.length();
          wildcardIndex++;
          i = pattern.indexOf(">", i);
          break;
        default:
          if (nameIndex == name.length() || patternChar != name.charAt(nameIndex++)) {
            return false;
          }
          break;
      }
    }
    return nameIndex == name.length();
  }

  public abstract boolean matches(String name);

  protected Iterable<ProguardWildcard> getWildcards() {
    return Collections::emptyIterator;
  }

  static Iterable<ProguardWildcard> getWildcardsOrEmpty(ProguardNameMatcher nameMatcher) {
    return nameMatcher == null ? Collections::emptyIterator : nameMatcher.getWildcards();
  }

  private static class MatchAllNames extends ProguardNameMatcher {
    private final ProguardWildcard wildcard;

    MatchAllNames() {
      this.wildcard = new Pattern("*");
    }

    @Override
    public boolean matches(String name) {
      wildcard.setCaptured(name);
      return true;
    }

    @Override
    protected Iterable<ProguardWildcard> getWildcards() {
      return ImmutableList.of(wildcard);
    }

    @Override
    public String toString() {
      return "*";
    }
  }

  private static class MatchNamePattern extends ProguardNameMatcher {

    private final String pattern;
    private final List<ProguardWildcard> wildcards;

    MatchNamePattern(IdentifierPatternWithWildcards identifierPatternWithWildcards) {
      this.pattern = identifierPatternWithWildcards.pattern;
      this.wildcards = identifierPatternWithWildcards.wildcards;
    }

    @Override
    public boolean matches(String name) {
      boolean matched = matchFieldOrMethodNameImpl(pattern, 0, name, 0, wildcards, 0);
      if (!matched) {
        wildcards.forEach(ProguardWildcard::clearCaptured);
      }
      return matched;
    }

    @Override
    protected Iterable<ProguardWildcard> getWildcards() {
      return wildcards;
    }

    @Override
    public String toString() {
      return pattern;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      return o instanceof MatchNamePattern && pattern.equals(((MatchNamePattern) o).pattern);
    }

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

  private static class MatchSpecificName extends ProguardNameMatcher {

    private final String name;

    MatchSpecificName(String name) {
      this.name = name;
    }

    @Override
    public boolean matches(String name) {
      return this.name.equals(name);
    }

    @Override
    public String toString() {
      return name;
    }

    @Override
    public boolean equals(Object o) {
      return o instanceof MatchSpecificName && name.equals(((MatchSpecificName) o).name);
    }

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