// Copyright (c) 2018, 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.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
import com.google.common.collect.Iterables;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class ProguardIfRule extends ProguardKeepRuleBase {

  private static final Origin NEVER_INLINE_ORIGIN =
      new Origin(Origin.root()) {
        @Override
        public String part() {
          return "<SYNTHETIC_NEVER_INLINE_RULE>";
        }
      };

  private static final Origin NO_HORIZONTAL_CLASS_MERGING_ORIGIN =
      new Origin(Origin.root()) {
        @Override
        public String part() {
          return "<SYNTHETIC_NO_HORIZONTAL_CLASS_MERGING_RULE>";
        }
      };

  private final Set<DexReference> preconditions;
  final ProguardKeepRule subsequentRule;

  private Map<DexField, DexField> inlinableFieldsInPrecondition = new ConcurrentHashMap<>();

  public Set<DexReference> getPreconditions() {
    return preconditions;
  }

  public ProguardKeepRule getSubsequentRule() {
    return subsequentRule;
  }

  public void addInlinableFieldMatchingPrecondition(DexField field) {
    if (inlinableFieldsInPrecondition != null) {
      inlinableFieldsInPrecondition.put(field, field);
    }
  }

  public Set<DexField> getAndClearInlinableFieldsMatchingPrecondition() {
    Set<DexField> fields = inlinableFieldsInPrecondition.keySet();
    inlinableFieldsInPrecondition = null;
    return fields;
  }

  public static class Builder extends ProguardKeepRuleBase.Builder<ProguardIfRule, Builder> {

    ProguardKeepRule subsequentRule = null;

    protected Builder() {
      super();
    }

    @Override
    public Builder self() {
      return this;
    }

    public void setSubsequentRule(ProguardKeepRule rule) {
      subsequentRule = rule;
    }

    @Override
    public ProguardIfRule build() {
      assert subsequentRule != null : "Option -if without a subsequent rule.";
      return new ProguardIfRule(
          origin,
          getPosition(),
          source,
          buildClassAnnotations(),
          classAccessFlags,
          negatedClassAccessFlags,
          classTypeNegated,
          classType,
          classNames,
          buildInheritanceAnnotations(),
          inheritanceClassName,
          inheritanceIsExtends,
          memberRules,
          subsequentRule,
          null);
    }
  }

  private ProguardIfRule(
      Origin origin,
      Position position,
      String source,
      List<ProguardTypeMatcher> classAnnotations,
      ProguardAccessFlags classAccessFlags,
      ProguardAccessFlags negatedClassAccessFlags,
      boolean classTypeNegated,
      ProguardClassType classType,
      ProguardClassNameList classNames,
      List<ProguardTypeMatcher> inheritanceAnnotations,
      ProguardTypeMatcher inheritanceClassName,
      boolean inheritanceIsExtends,
      List<ProguardMemberRule> memberRules,
      ProguardKeepRule subsequentRule,
      Set<DexReference> preconditions) {
    super(
        origin,
        position,
        source,
        classAnnotations,
        classAccessFlags,
        negatedClassAccessFlags,
        classTypeNegated,
        classType,
        classNames,
        inheritanceAnnotations,
        inheritanceClassName,
        inheritanceIsExtends,
        memberRules,
        ProguardKeepRuleType.CONDITIONAL,
        ProguardKeepRuleModifiers.builder().build());
    this.subsequentRule = subsequentRule;
    this.preconditions = preconditions;
  }

  public static Builder builder() {
    return new Builder();
  }

  @Override
  protected Iterable<ProguardWildcard> getWildcards() {
    return Iterables.concat(super.getWildcards(), subsequentRule.getWildcards());
  }

  @Override
  public boolean isProguardIfRule() {
    return true;
  }

  @Override
  public ProguardIfRule asProguardIfRule() {
    return this;
  }

  protected ProguardIfRule materialize(
      DexItemFactory dexItemFactory, Set<DexReference> preconditions) {
    return new ProguardIfRule(
        getOrigin(),
        getPosition(),
        getSource(),
        ProguardTypeMatcher.materializeList(getClassAnnotations(), dexItemFactory),
        getClassAccessFlags(),
        getNegatedClassAccessFlags(),
        getClassTypeNegated(),
        getClassType(),
        getClassNames().materialize(dexItemFactory),
        ProguardTypeMatcher.materializeList(getInheritanceAnnotations(), dexItemFactory),
        getInheritanceClassName() == null
            ? null
            : getInheritanceClassName().materialize(dexItemFactory),
        getInheritanceIsExtends(),
        getMemberRules() == null
            ? null
            : getMemberRules().stream()
                .map(memberRule -> memberRule.materialize(dexItemFactory))
                .collect(Collectors.toList()),
        subsequentRule.materialize(dexItemFactory),
        preconditions);
  }

  protected ClassInlineRule neverClassInlineRuleForCondition(DexItemFactory dexItemFactory) {
    return new ClassInlineRule(
        NEVER_INLINE_ORIGIN,
        Position.UNKNOWN,
        null,
        ProguardTypeMatcher.materializeList(getClassAnnotations(), dexItemFactory),
        getClassAccessFlags(),
        getNegatedClassAccessFlags(),
        getClassTypeNegated(),
        getClassType(),
        getClassNames().materialize(dexItemFactory),
        ProguardTypeMatcher.materializeList(getInheritanceAnnotations(), dexItemFactory),
        getInheritanceClassName() == null
            ? null
            : getInheritanceClassName().materialize(dexItemFactory),
        getInheritanceIsExtends(),
        getMemberRules(),
        ClassInlineRule.Type.NEVER);
  }

  /**
   * Consider the following rule, which requests that class Y should be kept if the method X.m() is
   * in the final output.
   *
   * <pre>
   * -if class X {
   *   public void m();
   * }
   * -keep class Y
   * </pre>
   *
   * When the {@link Enqueuer} finds that the method X.m() is reachable, it applies the subsequent
   * keep rule of the -if rule. Thus, Y will be marked as pinned, which guarantees, for example,
   * that it will not be merged into another class by the vertical class merger.
   *
   * <p>However, when the {@link Enqueuer} runs for the second time, it is important that X.m() has
   * not been inlined into another method Z.z(), because that would mean that Z.z() now relies on
   * the presence of Y, meanwhile Y will not be kept because X.m() is no longer present.
   *
   * <p>Therefore, each time the subsequent rule of an -if rule is applied, we also apply a
   * -neverinline rule for the condition of the -if rule.
   */
  protected InlineRule neverInlineRuleForCondition(
      DexItemFactory dexItemFactory, InlineRule.Type type) {
    if (getMemberRules() == null || getMemberRules().isEmpty()) {
      return null;
    }
    return new InlineRule(
        NEVER_INLINE_ORIGIN,
        Position.UNKNOWN,
        null,
        ProguardTypeMatcher.materializeList(getClassAnnotations(), dexItemFactory),
        getClassAccessFlags(),
        getNegatedClassAccessFlags(),
        getClassTypeNegated(),
        getClassType(),
        getClassNames().materialize(dexItemFactory),
        ProguardTypeMatcher.materializeList(getInheritanceAnnotations(), dexItemFactory),
        getInheritanceClassName() == null
            ? null
            : getInheritanceClassName().materialize(dexItemFactory),
        getInheritanceIsExtends(),
        getMemberRules().stream()
            .filter(rule -> rule.getRuleType().includesMethods())
            .map(memberRule -> memberRule.materialize(dexItemFactory))
            .collect(Collectors.toList()),
        type);
  }

  protected NoHorizontalClassMergingRule noHorizontalClassMergingRuleForCondition(
      DexItemFactory dexItemFactory) {
    List<ProguardMemberRule> memberRules = null;
    if (getMemberRules() != null) {
      memberRules =
          getMemberRules().stream()
              .map(memberRule -> memberRule.materialize(dexItemFactory))
              .collect(Collectors.toList());
    }

    return NoHorizontalClassMergingRule.builder()
        .setOrigin(NO_HORIZONTAL_CLASS_MERGING_ORIGIN)
        .addClassAnnotations(
            ProguardTypeMatcher.materializeList(getClassAnnotations(), dexItemFactory))
        .setClassAccessFlags(getClassAccessFlags())
        .setNegatedClassAccessFlags(getNegatedClassAccessFlags())
        .setClassType(getClassType())
        .setClassTypeNegated(getClassTypeNegated())
        .setClassNames(getClassNames().materialize(dexItemFactory))
        .addInheritanceAnnotations(
            ProguardTypeMatcher.materializeList(getInheritanceAnnotations(), dexItemFactory))
        .setInheritanceClassName(
            getInheritanceClassName() == null
                ? null
                : getInheritanceClassName().materialize(dexItemFactory))
        .setInheritanceIsExtends(getInheritanceIsExtends())
        .setMemberRules(memberRules)
        .build();
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof ProguardIfRule)) {
      return false;
    }
    ProguardIfRule other = (ProguardIfRule) o;
    if (!subsequentRule.equals(other.subsequentRule)) {
      return false;
    }
    return super.equals(o);
  }

  @Override
  public int hashCode() {
    return super.hashCode() * 3 + subsequentRule.hashCode();
  }

  @Override
  String typeString() {
    return "if";
  }

  @Override
  protected StringBuilder append(StringBuilder builder) {
    super.append(builder);
    builder.append('\n');
    return subsequentRule.append(builder);
  }
}
