// 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.DexClassAndField;
import com.android.tools.r8.graph.DexClassAndMethod;
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.shaking.RootSetUtils.RootSetBuilder;
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(
      DexClassAndField field,
      AppView<?> appView,
      Consumer<AnnotationMatchResult> matchedAnnotationsConsumer,
      DexStringCache stringCache) {
    DexField originalSignature =
        appView.graphLens().getOriginalFieldSignature(field.getReference());
    switch (getRuleType()) {
      case ALL:
      case ALL_FIELDS:
        {
          // Access flags check.
          if (!getAccessFlags().containsAll(field.getAccessFlags())
              || !getNegatedAccessFlags().containsNone(field.getAccessFlags())) {
            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.getAccessFlags())
              || !getNegatedAccessFlags().containsNone(field.getAccessFlags())) {
            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(
      DexClassAndMethod method,
      AppView<?> appView,
      Consumer<AnnotationMatchResult> matchedAnnotationsConsumer,
      DexStringCache stringCache) {
    DexMethod originalSignature =
        appView.graphLens().getOriginalMethodSignature(method.getReference());
    switch (getRuleType()) {
      case ALL_METHODS:
        if (method.getDefinition().isClassInitializer()) {
          break;
        }
        // Fall through for all other methods.

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

      case METHOD:
        // Check return type.
        if (!type.matches(originalSignature.getReturnType(), 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.getAccessFlags())
              || !getNegatedAccessFlags().containsNone(method.getAccessFlags())) {
            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.getParameters().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();
  }
}
