// 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.graph;

import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
import static com.android.tools.r8.kotlin.KotlinMetadataUtils.NO_KOTLIN_INFO;

import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.SingleValue;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.optimize.info.DefaultFieldOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.FieldOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.MutableFieldOptimizationInfo;
import com.android.tools.r8.kotlin.KotlinFieldLevelInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.Sets;

public class DexEncodedField extends DexEncodedMember<DexEncodedField, DexField> {
  public static final DexEncodedField[] EMPTY_ARRAY = {};

  public final DexField field;
  public final FieldAccessFlags accessFlags;
  private DexValue staticValue;
  private final boolean deprecated;

  private FieldOptimizationInfo optimizationInfo = DefaultFieldOptimizationInfo.getInstance();
  private KotlinFieldLevelInfo kotlinMemberInfo = NO_KOTLIN_INFO;

  public DexEncodedField(
      DexField field,
      FieldAccessFlags accessFlags,
      DexAnnotationSet annotations,
      DexValue staticValue,
      boolean deprecated) {
    super(annotations);
    this.field = field;
    this.accessFlags = accessFlags;
    this.staticValue = staticValue;
    this.deprecated = deprecated;
  }

  public DexEncodedField(
      DexField field,
      FieldAccessFlags accessFlags,
      DexAnnotationSet annotations,
      DexValue staticValue) {
    this(field, accessFlags, annotations, staticValue, false);
  }

  public DexType type() {
    return field.type;
  }

  public boolean isDeprecated() {
    return deprecated;
  }

  public boolean isProgramField(DexDefinitionSupplier definitions) {
    if (field.holder.isClassType()) {
      DexClass clazz = definitions.definitionFor(field.holder);
      return clazz != null && clazz.isProgramClass();
    }
    return false;
  }

  public FieldOptimizationInfo getOptimizationInfo() {
    return optimizationInfo;
  }

  public synchronized MutableFieldOptimizationInfo getMutableOptimizationInfo() {
    if (optimizationInfo.isDefaultFieldOptimizationInfo()) {
      MutableFieldOptimizationInfo mutableOptimizationInfo = new MutableFieldOptimizationInfo();
      optimizationInfo = mutableOptimizationInfo;
      return mutableOptimizationInfo;
    }
    assert optimizationInfo.isMutableFieldOptimizationInfo();
    return optimizationInfo.asMutableFieldOptimizationInfo();
  }

  public void setOptimizationInfo(MutableFieldOptimizationInfo info) {
    optimizationInfo = info;
  }

  public KotlinFieldLevelInfo getKotlinMemberInfo() {
    return kotlinMemberInfo;
  }

  @Override
  public FieldAccessFlags getAccessFlags() {
    return accessFlags;
  }

  public void setKotlinMemberInfo(KotlinFieldLevelInfo kotlinMemberInfo) {
    assert this.kotlinMemberInfo == NO_KOTLIN_INFO;
    this.kotlinMemberInfo = kotlinMemberInfo;
  }

  @Override
  void collectMixedSectionItems(MixedSectionCollection mixedItems) {
    annotations().collectMixedSectionItems(mixedItems);
  }

  @Override
  public String toString() {
    return "Encoded field " + field;
  }

  @Override
  public String toSmaliString() {
    return field.toSmaliString();
  }

  @Override
  public String toSourceString() {
    return field.toSourceString();
  }

  @Override
  public DexField toReference() {
    return field;
  }

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

  @Override
  public DexEncodedField asDexEncodedField() {
    return this;
  }

  @Override
  public ProgramField asProgramMember(DexDefinitionSupplier definitions) {
    return asProgramField(definitions);
  }

  public ProgramField asProgramField(DexDefinitionSupplier definitions) {
    assert holder().isClassType();
    DexProgramClass clazz = asProgramClassOrNull(definitions.definitionForHolder(field));
    if (clazz != null) {
      return new ProgramField(clazz, this);
    }
    return null;
  }

  public boolean isEnum() {
    return accessFlags.isEnum();
  }

  public boolean isFinal() {
    return accessFlags.isFinal();
  }

  @Override
  public boolean isStatic() {
    return accessFlags.isStatic();
  }

  public boolean isPackagePrivate() {
    return accessFlags.isPackagePrivate();
  }

  public boolean isPrivate() {
    return accessFlags.isPrivate();
  }

  public boolean isProtected() {
    return accessFlags.isProtected();
  }

  public boolean isPublic() {
    return accessFlags.isPublic();
  }

  @Override
  public boolean isStaticMember() {
    return isStatic();
  }

  public boolean isVolatile() {
    return accessFlags.isVolatile();
  }

  public boolean hasAnnotation() {
    return !annotations().isEmpty();
  }

  public boolean hasExplicitStaticValue() {
    assert accessFlags.isStatic();
    return staticValue != null;
  }

  public void setStaticValue(DexValue staticValue) {
    assert accessFlags.isStatic();
    assert staticValue != null;
    this.staticValue = staticValue;
  }

  public void clearStaticValue() {
    assert accessFlags.isStatic();
    this.staticValue = null;
  }

  public DexValue getStaticValue() {
    assert accessFlags.isStatic();
    return staticValue == null ? DexValue.defaultForType(field.type) : staticValue;
  }

  /**
   * Returns a const instructions if this field is a compile time final const.
   *
   * <p>NOTE: It is the responsibility of the caller to check if this field is pinned or not.
   */
  public Instruction valueAsConstInstruction(
      IRCode code, DebugLocalInfo local, AppView<AppInfoWithLiveness> appView) {
    boolean isWritten = appView.appInfo().isFieldWrittenByFieldPutInstruction(this);
    if (!isWritten) {
      // Since the field is not written, we can simply return the default value for the type.
      DexValue value = isStatic() ? getStaticValue() : DexValue.defaultForType(field.type);
      return value.asConstInstruction(appView, code, local);
    }

    // Check if we have a single value for the field according to the field optimization info.
    AbstractValue abstractValue = getOptimizationInfo().getAbstractValue();
    if (abstractValue.isSingleValue()) {
      SingleValue singleValue = abstractValue.asSingleValue();
      if (singleValue.isSingleFieldValue()
          && singleValue.asSingleFieldValue().getField() == field) {
        return null;
      }
      if (singleValue.isMaterializableInContext(appView, code.context())) {
        TypeElement type = TypeElement.fromDexType(field.type, maybeNull(), appView);
        return singleValue.createMaterializingInstruction(
            appView, code, TypeAndLocalInfoSupplier.create(type, local));
      }
    }

    // The only way to figure out whether the static value contains the final value is ensure the
    // value is not the default or check that <clinit> is not present.
    if (accessFlags.isFinal() && isStatic()) {
      DexClass clazz = appView.definitionFor(field.holder);
      if (clazz == null || clazz.hasClassInitializer()) {
        return null;
      }
      DexValue staticValue = getStaticValue();
      if (!staticValue.isDefault(field.type)) {
        return staticValue.asConstInstruction(appView, code, local);
      }
    }

    return null;
  }

  public boolean mayTriggerClassInitializationSideEffects(
      AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
    // Only static field matters when it comes to class initialization side effects.
    if (!isStatic()) {
      return false;
    }
    DexClass clazz = appView.definitionFor(field.holder);
    if (clazz == null) {
      return true;
    }
    if (clazz.classInitializationMayHaveSideEffects(
        appView,
        // Types that are a super type of the current context are guaranteed to be initialized
        // already.
        type -> appView.appInfo().isSubtype(context.getHolderType(), type),
        Sets.newIdentityHashSet())) {
      // Ignore class initialization side-effects for dead proto extension fields to ensure that
      // we force replace these field reads by null.
      boolean ignore =
          appView.withGeneratedExtensionRegistryShrinker(
              shrinker -> shrinker.isDeadProtoExtensionField(field), false);
      return !ignore;
    }
    return false;
  }

  public DexEncodedField toTypeSubstitutedField(DexField field) {
    if (this.field == field) {
      return this;
    }
    DexEncodedField result = new DexEncodedField(field, accessFlags, annotations(), staticValue);
    result.optimizationInfo =
        optimizationInfo.isMutableFieldOptimizationInfo()
            ? optimizationInfo.asMutableFieldOptimizationInfo().mutableCopy()
            : DefaultFieldOptimizationInfo.getInstance();
    return result;
  }

  public boolean validateDexValue(DexItemFactory factory) {
    if (!accessFlags.isStatic() || staticValue == null) {
      return true;
    }
    if (field.type.isPrimitiveType()) {
      assert staticValue.getType(factory) == field.type
          : "Static " + field + " has invalid static value " + staticValue + ".";
    }
    if (staticValue.isDexValueNull()) {
      assert field.type.isReferenceType() : "Static " + field + " has invalid null static value.";
    }
    // TODO(b/150593449): Support non primitive DexValue (String, enum) and add assertions.
    return true;
  }
}
