// 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.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClassResolutionResult;
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 isProguardCheckDiscardRule() {
    return false;
  }

  public ProguardCheckDiscardRule asProguardCheckDiscardRule() {
    return null;
  }

  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 ClassResolutionResult contextIndependentDefinitionForWithResolutionResult(
                DexType type) {
              throw new Unreachable("Add support for multiple definitions with rule evaluation");
            }

            @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;
  }
}
