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

import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
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.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.kotlin.KotlinFieldLevelInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.ConsumerUtils;
import com.android.tools.r8.utils.structural.StructuralItem;
import com.android.tools.r8.utils.structural.StructuralMapping;
import com.android.tools.r8.utils.structural.StructuralSpecification;
import java.util.function.Consumer;
import java.util.function.Function;

public class DexEncodedField extends DexEncodedMember<DexEncodedField, DexField>
    implements StructuralItem<DexEncodedField> {

  public static final boolean D8_R8_SYNTHESIZED = true;
  public static final boolean NOT_DEPRECATED = false;
  public static final DexValue NO_STATIC_VALUE = null;
  public static final DexEncodedField[] EMPTY_ARRAY = {};

  public final FieldAccessFlags accessFlags;
  private DexValue staticValue;
  private final boolean deprecated;
  /** Generic signature information if the attribute is present in the input */
  private FieldTypeSignature genericSignature;

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

  private static void specify(StructuralSpecification<DexEncodedField, ?> spec) {
    spec.withItem(DexEncodedField::getReference)
        .withItem(DexEncodedField::getAccessFlags)
        .withNullableItem(f -> f.staticValue)
        .withBool(DexEncodedField::isDeprecated)
        // TODO(b/171867022): The generic signature should be part of the definition.
        .withAssert(f -> f.genericSignature.hasNoSignature());
    // TODO(b/171867022): Should the optimization info and member info be part of the definition?
  }

  public DexEncodedField(DexField field, FieldAccessFlags accessFlags) {
    this(field, accessFlags, FieldTypeSignature.noSignature(), DexAnnotationSet.empty(), null);
  }

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

  public DexEncodedField(
      DexField field,
      FieldAccessFlags accessFlags,
      FieldTypeSignature genericSignature,
      DexAnnotationSet annotations,
      DexValue staticValue,
      boolean deprecated) {
    this(
        field,
        accessFlags,
        genericSignature,
        annotations,
        staticValue,
        deprecated,
        false,
        AndroidApiLevel.UNKNOWN);
  }

  public DexEncodedField(
      DexField field,
      FieldAccessFlags accessFlags,
      FieldTypeSignature genericSignature,
      DexAnnotationSet annotations,
      DexValue staticValue,
      boolean deprecated,
      boolean d8R8Synthesized,
      AndroidApiLevel apiLevel) {
    super(field, annotations, d8R8Synthesized, apiLevel);
    this.accessFlags = accessFlags;
    this.staticValue = staticValue;
    this.deprecated = deprecated;
    this.genericSignature = genericSignature;
    assert genericSignature != null;
    assert GenericSignatureUtils.verifyNoDuplicateGenericDefinitions(genericSignature, annotations);
  }

  @Override
  public StructuralMapping<DexEncodedField> getStructuralMapping() {
    return DexEncodedField::specify;
  }

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

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

  public boolean isDeprecated() {
    return deprecated;
  }

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

  @Override
  public FieldOptimizationInfo getOptimizationInfo() {
    return optimizationInfo;
  }

  @Override
  public AndroidApiLevel getApiLevel() {
    return getApiLevelForDefinition();
  }

  public synchronized MutableFieldOptimizationInfo getMutableOptimizationInfo() {
    MutableFieldOptimizationInfo mutableInfo = optimizationInfo.toMutableOptimizationInfo();
    optimizationInfo = mutableInfo;
    return mutableInfo;
  }

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

  @Override
  public KotlinFieldLevelInfo getKotlinInfo() {
    return kotlinMemberInfo;
  }

  @Override
  public void clearKotlinInfo() {
    kotlinMemberInfo = getNoKotlinInfo();
  }

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

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

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

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

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

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

  public DexType getType() {
    return getReference().getType();
  }

  public TypeElement getTypeElement(AppView<?> appView) {
    return getReference().getTypeElement(appView);
  }

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

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

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

  @Override
  public <T> T apply(
      Function<DexEncodedField, T> fieldConsumer, Function<DexEncodedMethod, T> methodConsumer) {
    return fieldConsumer.apply(this);
  }

  public ProgramField asProgramField(DexDefinitionSupplier definitions) {
    assert getHolderType().isClassType();
    DexProgramClass clazz = asProgramClassOrNull(definitions.definitionForHolder(getReference()));
    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 isProtected() {
    return accessFlags.isProtected();
  }

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

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

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

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

  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(getReference().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(getReference().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() == getReference()) {
        return null;
      }
      if (singleValue.isMaterializableInContext(appView, code.context())) {
        TypeElement type = TypeElement.fromDexType(getReference().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(getReference().holder);
      if (clazz == null || clazz.hasClassInitializer()) {
        return null;
      }
      DexValue staticValue = getStaticValue();
      if (!staticValue.isDefault(getReference().type)) {
        return staticValue.asConstInstruction(appView, code, local);
      }
    }

    return null;
  }

  public DexEncodedField toTypeSubstitutedField(DexField field) {
    return toTypeSubstitutedField(field, ConsumerUtils.emptyConsumer());
  }

  public DexEncodedField toTypeSubstitutedField(DexField field, Consumer<Builder> consumer) {
    if (this.getReference() == field) {
      return this;
    }
    return builder(this).setField(field).apply(consumer).build();
  }

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

  public FieldTypeSignature getGenericSignature() {
    return genericSignature;
  }

  public void setGenericSignature(FieldTypeSignature genericSignature) {
    assert genericSignature != null;
    this.genericSignature = genericSignature;
  }

  @Override
  public void clearGenericSignature() {
    this.genericSignature = FieldTypeSignature.noSignature();
  }

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

  private static Builder builder(DexEncodedField from) {
    return new Builder(from);
  }

  public static class Builder {

    private DexField field;
    private DexAnnotationSet annotations = DexAnnotationSet.empty();
    private FieldAccessFlags accessFlags;
    private FieldTypeSignature genericSignature = FieldTypeSignature.noSignature();
    private DexValue staticValue;
    private AndroidApiLevel apiLevel;
    private FieldOptimizationInfo optimizationInfo = DefaultFieldOptimizationInfo.getInstance();
    private boolean deprecated;
    private boolean d8R8Synthesized;
    private Consumer<DexEncodedField> buildConsumer = ConsumerUtils.emptyConsumer();

    Builder() {}

    Builder(DexEncodedField from) {
      // Copy all the mutable state of a DexEncodedField here.
      field = from.getReference();
      accessFlags = from.accessFlags.copy();
      // TODO(b/169923358): Consider removing the fieldSignature here.
      genericSignature = from.getGenericSignature();
      annotations = from.annotations();
      staticValue = from.staticValue;
      apiLevel = from.getApiLevel();
      optimizationInfo =
          from.optimizationInfo.isMutableOptimizationInfo()
              ? from.optimizationInfo.asMutableFieldOptimizationInfo().mutableCopy()
              : from.optimizationInfo;
      deprecated = from.isDeprecated();
      d8R8Synthesized = from.isD8R8Synthesized();
    }

    public Builder apply(Consumer<Builder> consumer) {
      consumer.accept(this);
      return this;
    }

    public Builder modifyAccessFlags(Consumer<FieldAccessFlags> consumer) {
      consumer.accept(accessFlags);
      return this;
    }

    public Builder setAbstractValue(
        AbstractValue abstractValue, AppView<AppInfoWithLiveness> appView) {
      return addBuildConsumer(
          fixedUpField ->
              OptimizationFeedbackSimple.getInstance()
                  .recordFieldHasAbstractValue(fixedUpField, appView, abstractValue));
    }

    public Builder clearAnnotations() {
      return setAnnotations(DexAnnotationSet.empty());
    }

    public Builder setAnnotations(DexAnnotationSet annotations) {
      this.annotations = annotations;
      return this;
    }

    private Builder addBuildConsumer(Consumer<DexEncodedField> consumer) {
      this.buildConsumer = this.buildConsumer.andThen(consumer);
      return this;
    }

    public Builder setField(DexField field) {
      this.field = field;
      return this;
    }

    public Builder setAccessFlags(FieldAccessFlags accessFlags) {
      this.accessFlags = accessFlags;
      return this;
    }

    public Builder setD8R8Synthesized() {
      this.d8R8Synthesized = true;
      return this;
    }

    public Builder setApiLevel(AndroidApiLevel apiLevel) {
      this.apiLevel = apiLevel;
      return this;
    }

    public DexEncodedField build() {
      assert field != null;
      assert accessFlags != null;
      assert genericSignature != null;
      assert annotations != null;
      assert apiLevel != null;
      DexEncodedField dexEncodedField =
          new DexEncodedField(
              field,
              accessFlags,
              genericSignature,
              annotations,
              staticValue,
              deprecated,
              d8R8Synthesized,
              apiLevel);
      dexEncodedField.optimizationInfo = optimizationInfo;
      buildConsumer.accept(dexEncodedField);
      return dexEncodedField;
    }
  }
}
