// 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.androidapi.ComputedApiLevel;
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.kotlin.KotlinMetadataUtils;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
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 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();

  // Mark indicating if this field has been identified as potentially inlined by javac.
  // This is to ensure consistent tracing in the second round of tree shaking. Remove this field
  // once conditional rules are represented by rule-instances rather than reevaluating rule-schemas.
  private boolean isInlinableByJavaC = false;

  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?
  }

  private DexEncodedField(
      DexField field,
      FieldAccessFlags accessFlags,
      FieldTypeSignature genericSignature,
      DexAnnotationSet annotations,
      DexValue staticValue,
      ComputedApiLevel apiLevel,
      boolean deprecated,
      boolean d8R8Synthesized) {
    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 ComputedApiLevel 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();
  }

  @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(AppView<?> appView, DexField field) {
    return toTypeSubstitutedField(appView, field, ConsumerUtils.emptyConsumer());
  }

  public DexEncodedField toTypeSubstitutedField(
      AppView<?> appView, DexField field, Consumer<Builder> consumer) {
    if (this.getReference() == field) {
      return this;
    }
    return builder(this)
        .setField(field)
        .disableAndroidApiLevelCheckIf(
            !appView.options().apiModelingOptions().enableApiCallerIdentification
                || !appView.enableWholeProgramOptimizations())
        .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(false);
  }

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

  public static Builder syntheticBuilder() {
    return new Builder(true);
  }

  public void markAsInlinableByJavaC() {
    isInlinableByJavaC = true;
  }

  public boolean getIsInlinableByJavaC() {
    return isInlinableByJavaC;
  }

  public boolean getOrComputeIsInlinableByJavaC(DexItemFactory dexItemFactory) {
    if (getIsInlinableByJavaC()) {
      return true;
    }
    if (!isStatic() || !isFinal()) {
      return false;
    }
    if (!hasExplicitStaticValue()) {
      return false;
    }
    if (getType().isPrimitiveType()) {
      return true;
    }
    if (getType() != dexItemFactory.stringType) {
      return false;
    }
    if (!getStaticValue().isDexValueString()) {
      return false;
    }
    markAsInlinableByJavaC();
    return true;
  }

  public static class Builder {

    private DexField field;
    private DexAnnotationSet annotations = DexAnnotationSet.empty();
    private FieldAccessFlags accessFlags;
    private FieldTypeSignature genericSignature = FieldTypeSignature.noSignature();
    private KotlinFieldLevelInfo kotlinInfo = KotlinMetadataUtils.getNoKotlinInfo();
    private DexValue staticValue = null;
    private ComputedApiLevel apiLevel = ComputedApiLevel.notSet();
    private FieldOptimizationInfo optimizationInfo = DefaultFieldOptimizationInfo.getInstance();
    private boolean deprecated;
    private final boolean d8R8Synthesized;
    private Consumer<DexEncodedField> buildConsumer = ConsumerUtils.emptyConsumer();

    // Checks to impose on the built method. They should always be active to start with and be
    // lowered on the use site.
    private boolean checkAndroidApiLevel = true;

    private Builder(boolean d8R8Synthesized) {
      this.d8R8Synthesized = d8R8Synthesized;
    }

    private Builder(boolean d8R8Synthesized, DexEncodedField from) {
      // Copy all the mutable state of a DexEncodedField here.
      field = from.getReference();
      accessFlags = from.accessFlags.copy();
      genericSignature = from.getGenericSignature();
      kotlinInfo = from.getKotlinInfo();
      annotations = from.annotations();
      staticValue = from.staticValue;
      apiLevel = from.getApiLevel();
      optimizationInfo =
          from.optimizationInfo.isMutableOptimizationInfo()
              ? from.optimizationInfo.asMutableFieldOptimizationInfo().mutableCopy()
              : from.optimizationInfo;
      deprecated = from.isDeprecated();
      this.d8R8Synthesized = d8R8Synthesized;
    }

    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 setApiLevel(ComputedApiLevel apiLevel) {
      this.apiLevel = apiLevel;
      return this;
    }

    public Builder setGenericSignature(FieldTypeSignature genericSignature) {
      this.genericSignature = genericSignature;
      return this;
    }

    public Builder setStaticValue(DexValue staticValue) {
      this.staticValue = staticValue;
      return this;
    }

    public Builder setDeprecated(boolean deprecated) {
      this.deprecated = deprecated;
      return this;
    }

    public Builder disableAndroidApiLevelCheck() {
      return disableAndroidApiLevelCheckIf(true);
    }

    public Builder disableAndroidApiLevelCheckIf(boolean shouldDisable) {
      if (shouldDisable) {
        checkAndroidApiLevel = false;
      }
      return this;
    }

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