// Copyright (c) 2017, 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.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.StreamSupport;

public abstract class ProguardConfigurationRule extends ProguardClassSpecification {

  private boolean used = false;
  // TODO(b/164019179): Since we are using the rule language for tracing main dex we can end up in
  //  a situation where the references to types are dead.
  private boolean canReferenceDeadTypes = false;

  ProguardConfigurationRule(
      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) {
    super(
        origin,
        position,
        source,
        classAnnotations,
        classAccessFlags,
        negatedClassAccessFlags,
        classTypeNegated,
        classType,
        classNames,
        inheritanceAnnotations,
        inheritanceClassName,
        inheritanceIsExtends,
        memberRules);
  }

  public boolean isUsed() {
    return used;
  }

  public void markAsUsed() {
    used = true;
  }

  public boolean isProguardKeepRule() {
    return false;
  }

  public ProguardKeepRule asProguardKeepRule() {
    return null;
  }

  public boolean isProguardIfRule() {
    return false;
  }

  public ProguardIfRule asProguardIfRule() {
    return null;
  }

  public boolean isClassInlineRule() {
    return false;
  }

  public ClassInlineRule asClassInlineRule() {
    return null;
  }

  public boolean isReprocessClassInitializerRule() {
    return false;
  }

  public ReprocessClassInitializerRule asReprocessClassInitializerRule() {
    return null;
  }

  public boolean isReprocessMethodRule() {
    return false;
  }

  public ReprocessMethodRule asReprocessMethodRule() {
    return null;
  }

  public void canReferenceDeadTypes() {
    this.canReferenceDeadTypes = true;
  }

  Iterable<DexProgramClass> relevantCandidatesForRule(
      AppView<? extends AppInfoWithClassHierarchy> appView,
      SubtypingInfo subtypingInfo,
      Iterable<DexProgramClass> defaultValue) {
    List<DexType> specificTypes = getClassNames().asSpecificDexTypes();
    if (specificTypes != null) {
      return DexProgramClass.asProgramClasses(
          specificTypes,
          new DexDefinitionSupplier() {
            @Override
            public DexClass definitionFor(DexType type) {
              if (canReferenceDeadTypes) {
                return appView.appInfo().definitionForWithoutExistenceAssert(type);
              }
              return appView.definitionFor(type);
            }

            @Override
            public DexItemFactory dexItemFactory() {
              return appView.dexItemFactory();
            }
          });
    }
    if (hasInheritanceClassName() && getInheritanceClassName().hasSpecificType()) {
      DexType type = getInheritanceClassName().getSpecificType();
      if (appView.verticallyMergedClasses() != null
          && appView.verticallyMergedClasses().hasBeenMergedIntoSubtype(type)) {
        DexType target = appView.verticallyMergedClasses().getTargetFor(type);
        DexClass clazz = appView.definitionFor(target);
        assert clazz != null && clazz.isProgramClass();
        return Iterables.concat(
            ImmutableList.of(clazz.asProgramClass()),
            DexProgramClass.asProgramClasses(subtypingInfo.subtypes(type), appView));
      } else {
        return DexProgramClass.asProgramClasses(subtypingInfo.subtypes(type), appView);
      }
    }
    return defaultValue;
  }

  abstract String typeString();

  String modifierString() {
    return null;
  }

  public boolean applyToNonProgramClasses() {
    return false;
  }

  protected Iterable<ProguardWildcard> getWildcards() {
    List<ProguardMemberRule> memberRules = getMemberRules();
    return Iterables.concat(
        ProguardTypeMatcher.getWildcardsOrEmpty(getClassAnnotations()),
        ProguardClassNameList.getWildcardsOrEmpty(getClassNames()),
        ProguardTypeMatcher.getWildcardsOrEmpty(getInheritanceAnnotations()),
        ProguardTypeMatcher.getWildcardsOrEmpty(getInheritanceClassName()),
        memberRules != null
            ? memberRules.stream()
                    .map(ProguardMemberRule::getWildcards)
                    .flatMap(it -> StreamSupport.stream(it.spliterator(), false))
                ::iterator
            : Collections::emptyIterator);
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof ProguardConfigurationRule)) {
      return false;
    }
    ProguardConfigurationRule that = (ProguardConfigurationRule) o;
    if (used != that.used) {
      return false;
    }
    if (!Objects.equals(typeString(), that.typeString())) {
      return false;
    }
    if (!Objects.equals(modifierString(), that.modifierString())) {
      return false;
    }
    return super.equals(that);
  }

  @Override
  public int hashCode() {
    int result = 3 * typeString().hashCode();
    result = 3 * result + (used ? 1 : 0);
    String modifier = modifierString();
    result = 3 * result + (modifier != null ? modifier.hashCode() : 0);
    return result + super.hashCode();
  }

  @Override
  protected StringBuilder append(StringBuilder builder, boolean includeMemberRules) {
    builder.append("-");
    builder.append(typeString());
    StringUtils.appendNonEmpty(builder, ",", modifierString(), null);
    builder.append(' ');
    super.append(builder, includeMemberRules);
    return builder;
  }
}
