// 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.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.shaking.ProguardConfigurationParser.IdentifierPatternWithWildcards;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.Iterables;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

public class ProguardMemberRule {

  public static class Builder {

    private List<ProguardTypeMatcher> annotations = Collections.emptyList();
    private ProguardAccessFlags accessFlags = new ProguardAccessFlags();
    private ProguardAccessFlags negatedAccessFlags = new ProguardAccessFlags();
    private ProguardMemberType ruleType;
    private ProguardTypeMatcher type;
    private ProguardNameMatcher name;
    private List<ProguardTypeMatcher> arguments;
    private ProguardMemberRuleReturnValue returnValue;

    private Builder() {}

    public void setAnnotations(List<ProguardTypeMatcher> annotations) {
      assert annotations != null;
      this.annotations = annotations;
    }

    public ProguardAccessFlags getAccessFlags() {
      return accessFlags;
    }

    public Builder setAccessFlags(ProguardAccessFlags flags) {
      accessFlags = flags;
      return this;
    }

    public ProguardAccessFlags getNegatedAccessFlags() {
      return negatedAccessFlags;
    }

    public void setNegatedAccessFlags(ProguardAccessFlags flags) {
      negatedAccessFlags = flags;
    }

    public Builder setRuleType(ProguardMemberType ruleType) {
      this.ruleType = ruleType;
      return this;
    }

    public ProguardTypeMatcher getTypeMatcher() {
      return type;
    }

    public Builder setTypeMatcher(ProguardTypeMatcher type) {
      this.type = type;
      return this;
    }

    public Builder setName(IdentifierPatternWithWildcards identifierPatternWithWildcards) {
      this.name = ProguardNameMatcher.create(identifierPatternWithWildcards);
      return this;
    }

    public Builder setArguments(List<ProguardTypeMatcher> arguments) {
      this.arguments = arguments;
      return this;
    }

    public Builder setReturnValue(ProguardMemberRuleReturnValue value) {
      returnValue = value;
      return this;
    }

    public boolean isValid() {
      return ruleType != null;
    }

    public ProguardMemberRule build() {
      assert isValid();
      return new ProguardMemberRule(
          annotations,
          accessFlags,
          negatedAccessFlags,
          ruleType,
          type,
          name,
          arguments,
          returnValue);
    }
  }

  private final List<ProguardTypeMatcher> annotations;
  private final ProguardAccessFlags accessFlags;
  private final ProguardAccessFlags negatedAccessFlags;
  private final ProguardMemberType ruleType;
  private final ProguardTypeMatcher type;
  private final ProguardNameMatcher name;
  private final List<ProguardTypeMatcher> arguments;
  private final ProguardMemberRuleReturnValue returnValue;

  private ProguardMemberRule(
      List<ProguardTypeMatcher> annotations,
      ProguardAccessFlags accessFlags,
      ProguardAccessFlags negatedAccessFlags,
      ProguardMemberType ruleType,
      ProguardTypeMatcher type,
      ProguardNameMatcher name,
      List<ProguardTypeMatcher> arguments,
      ProguardMemberRuleReturnValue returnValue) {
    this.annotations = annotations;
    this.accessFlags = accessFlags;
    this.negatedAccessFlags = negatedAccessFlags;
    this.ruleType = ruleType;
    this.type = type;
    this.name = name;
    this.arguments = arguments != null ? Collections.unmodifiableList(arguments) : null;
    this.returnValue = returnValue;
  }

  /**
   * Create a new empty builder.
   */
  public static Builder builder() {
    return new Builder();
  }

  public List<ProguardTypeMatcher> getAnnotations() {
    return annotations;
  }

  public ProguardAccessFlags getAccessFlags() {
    return accessFlags;
  }

  public ProguardAccessFlags getNegatedAccessFlags() {
    return negatedAccessFlags;
  }

  public ProguardMemberType getRuleType() {
    return ruleType;
  }

  public ProguardTypeMatcher getType() {
    return type;
  }

  public ProguardNameMatcher getName() {
    return name;
  }

  public List<ProguardTypeMatcher> getArguments() {
    return arguments;
  }

  public boolean hasReturnValue() {
    return returnValue != null;
  }

  public ProguardMemberRuleReturnValue getReturnValue() {
    return returnValue;
  }

  public ProguardTypeMatcher getTypeMatcher() {
    return type;
  }

  public boolean matches(
      DexEncodedField field,
      AppView<?> appView,
      Consumer<AnnotationMatchResult> matchedAnnotationsConsumer,
      DexStringCache stringCache) {
    DexField originalSignature = appView.graphLense().getOriginalFieldSignature(field.field);
    switch (getRuleType()) {
      case ALL:
      case ALL_FIELDS:
        {
          // Access flags check.
          if (!getAccessFlags().containsAll(field.accessFlags)
              || !getNegatedAccessFlags().containsNone(field.accessFlags)) {
            break;
          }
          // Annotations check.
          return RootSetBuilder.containsAllAnnotations(
              annotations, field, matchedAnnotationsConsumer);
        }

      case FIELD:
        {
          // Name check.
          String name = stringCache.lookupString(originalSignature.name);
          if (!getName().matches(name)) {
            break;
          }
          // Access flags check.
          if (!getAccessFlags().containsAll(field.accessFlags)
              || !getNegatedAccessFlags().containsNone(field.accessFlags)) {
            break;
          }
          // Type check.
          if (!getType().matches(originalSignature.type, appView)) {
            break;
          }
          // Annotations check
          return RootSetBuilder.containsAllAnnotations(
              annotations, field, matchedAnnotationsConsumer);
        }

      case ALL_METHODS:
      case CLINIT:
      case INIT:
      case CONSTRUCTOR:
      case METHOD:
        break;
    }
    return false;
  }

  public boolean matches(
      DexEncodedMethod method,
      AppView<?> appView,
      Consumer<AnnotationMatchResult> matchedAnnotationsConsumer,
      DexStringCache stringCache) {
    DexMethod originalSignature = appView.graphLense().getOriginalMethodSignature(method.method);
    switch (getRuleType()) {
      case ALL_METHODS:
        if (method.isClassInitializer()) {
          break;
        }
        // Fall through for all other methods.

      case ALL:
        {
          // Access flags check.
          if (!getAccessFlags().containsAll(method.accessFlags)
              || !getNegatedAccessFlags().containsNone(method.accessFlags)) {
            break;
          }
          // Annotations check.
          return RootSetBuilder.containsAllAnnotations(
              annotations, method, matchedAnnotationsConsumer);
        }

      case METHOD:
        // Check return type.
        if (!type.matches(originalSignature.proto.returnType, appView)) {
          break;
        }
        // Fall through for access flags, name and arguments.

      case CONSTRUCTOR:
      case INIT:
      case CLINIT:
        {
          // Name check.
          String name = stringCache.lookupString(originalSignature.name);
          if (!getName().matches(name)) {
            break;
          }
          // Access flags check.
          if (!getAccessFlags().containsAll(method.accessFlags)
              || !getNegatedAccessFlags().containsNone(method.accessFlags)) {
            break;
          }
          // Annotations check.
          if (!RootSetBuilder.containsAllAnnotations(
              annotations, method, matchedAnnotationsConsumer)) {
            return false;
          }
          // Parameter types check.
          List<ProguardTypeMatcher> arguments = getArguments();
          if (arguments.size() == 1 && arguments.get(0).isTripleDotPattern()) {
            return true;
          }
          DexType[] parameters = originalSignature.proto.parameters.values;
          if (parameters.length != arguments.size()) {
            break;
          }
          for (int i = 0; i < parameters.length; i++) {
            if (!arguments.get(i).matches(parameters[i], appView)) {
              return false;
            }
          }
          // All parameters matched.
          return true;
        }

      case ALL_FIELDS:
      case FIELD:
        break;
    }
    return false;
  }

  public boolean isSpecific() {
    switch (getRuleType()) {
      case ALL:
        // fall through
      case ALL_FIELDS:
        // fall through
      case ALL_METHODS:
        return false;
      default:
        return Iterables.size(getWildcards()) == 0;
    }
  }

  Iterable<ProguardWildcard> getWildcards() {
    return Iterables.concat(
        ProguardTypeMatcher.getWildcardsOrEmpty(annotations),
        ProguardTypeMatcher.getWildcardsOrEmpty(type),
        ProguardNameMatcher.getWildcardsOrEmpty(name),
        arguments != null
            ? arguments.stream()
                    .map(ProguardTypeMatcher::getWildcards)
                    .flatMap(it -> StreamSupport.stream(it.spliterator(), false))
                ::iterator
            : Collections::emptyIterator);
  }

  ProguardMemberRule materialize(DexItemFactory dexItemFactory) {
    return new ProguardMemberRule(
        ProguardTypeMatcher.materializeList(getAnnotations(), dexItemFactory),
        getAccessFlags(),
        getNegatedAccessFlags(),
        getRuleType(),
        getType() == null ? null : getType().materialize(dexItemFactory),
        getName() == null ? null : getName().materialize(),
        getArguments() == null
            ? null
            : getArguments().stream()
                .map(argument -> argument.materialize(dexItemFactory))
                .collect(Collectors.toList()),
        getReturnValue());
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof ProguardMemberRule)) {
      return false;
    }

    ProguardMemberRule that = (ProguardMemberRule) o;

    if (!annotations.equals(that.annotations)) {
      return false;
    }
    if (!accessFlags.equals(that.accessFlags)) {
      return false;
    }
    if (!negatedAccessFlags.equals(that.negatedAccessFlags)) {
      return false;
    }
    if (ruleType != that.ruleType) {
      return false;
    }
    if (name != null ? !name.equals(that.name) : that.name != null) {
      return false;
    }
    if (type != null ? !type.equals(that.type) : that.type != null) {
      return false;
    }
    return arguments != null ? arguments.equals(that.arguments) : that.arguments == null;
  }

  @Override
  public int hashCode() {
    int result = annotations.hashCode();
    result = 31 * result + accessFlags.hashCode();
    result = 31 * result + negatedAccessFlags.hashCode();
    result = 31 * result + (ruleType != null ? ruleType.hashCode() : 0);
    result = 31 * result + (type != null ? type.hashCode() : 0);
    result = 31 * result + (name != null ? name.hashCode() : 0);
    result = 31 * result + (arguments != null ? arguments.hashCode() : 0);
    return result;
  }

  @Override
  public String toString() {
    StringBuilder result = new StringBuilder();
    for (ProguardTypeMatcher annotation : annotations) {
      ProguardKeepRule.appendNonEmpty(result, "@", annotation, " ");
    }
    ProguardKeepRule.appendNonEmpty(result, null, accessFlags, " ");
    ProguardKeepRule
        .appendNonEmpty(result, null, negatedAccessFlags.toString().replace(" ", " !"), " ");
    switch (getRuleType()) {
      case ALL_FIELDS:
        result.append("<fields>");
        break;
      case ALL_METHODS:
        result.append("<methods>");
        break;
      case METHOD:
        result.append(getType());
        result.append(' ');
        // Fall through for rest of method signature.
      case CONSTRUCTOR:
      case CLINIT:
      case INIT: {
        result.append(getName());
        result.append('(');
        result.append(StringUtils.join(getArguments(), ","));
        result.append(')');
        break;
      }
      case FIELD: {
        result.append(getType());
        result.append(' ');
        result.append(getName());
        break;
      }
      case ALL: {
        result.append("*");
        break;
      }
      default:
        throw new Unreachable("Unknown kind of member rule");
    }
    if (hasReturnValue()) {
      result.append(returnValue.toString());
    }
    return result.toString();
  }

  public static ProguardMemberRule defaultKeepAllRule() {
    ProguardMemberRule.Builder ruleBuilder = new ProguardMemberRule.Builder();
    ruleBuilder.setRuleType(ProguardMemberType.ALL);
    return ruleBuilder.build();
  }
}
