// 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 com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.structural.CompareToVisitor;
import com.android.tools.r8.utils.structural.StructuralMapping;
import com.android.tools.r8.utils.structural.StructuralSpecification;
import java.util.Collections;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

public class DexField extends DexMember<DexEncodedField, DexField> {

  public final DexType type;

  DexField(DexType holder, DexType type, DexString name, boolean skipNameValidationForTesting) {
    super(holder, name);
    this.type = type;
    if (!skipNameValidationForTesting && !name.isValidFieldName()) {
      throw new CompilationError(
          "Field name '" + name.toString() + "' cannot be represented in dex format.");
    }
  }

  private static void specify(StructuralSpecification<DexField, ?> spec) {
    spec.withItem(DexField::getHolderType).withItem(DexField::getName).withItem(DexField::getType);
  }

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

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

  public DexType getType() {
    return type;
  }

  @Override
  public DexEncodedField lookupOnClass(DexClass clazz) {
    return clazz != null ? clazz.lookupField(this) : null;
  }

  @Override
  public DexClassAndField lookupMemberOnClass(DexClass clazz) {
    return clazz != null ? clazz.lookupClassField(this) : null;
  }

  @Override
  public ProgramField lookupOnProgramClass(DexProgramClass clazz) {
    return clazz != null ? clazz.lookupProgramField(this) : null;
  }

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

  @Override
  public <T> T apply(
      Function<DexType, T> classConsumer,
      Function<DexField, T> fieldConsumer,
      Function<DexMethod, T> methodConsumer) {
    return fieldConsumer.apply(this);
  }

  @Override
  public void accept(
      Consumer<DexType> classConsumer,
      Consumer<DexField> fieldConsumer,
      Consumer<DexMethod> methodConsumer) {
    fieldConsumer.accept(this);
  }

  @Override
  public <T> void accept(
      BiConsumer<DexType, T> classConsumer,
      BiConsumer<DexField, T> fieldConsumer,
      BiConsumer<DexMethod, T> methodConsumer,
      T arg) {
    fieldConsumer.accept(this, arg);
  }

  @Override
  public int computeHashCode() {
    return holder.hashCode()
        + type.hashCode() * 7
        + name.hashCode() * 31;
  }

  @Override
  public boolean computeEquals(Object other) {
    if (other instanceof DexField) {
      DexField o = (DexField) other;
      return holder.equals(o.holder)
          && type.equals(o.type)
          && name.equals(o.name);
    }
    return false;
  }

  @Override
  public String toString() {
    return "Field " + type + " " + holder + "." + name;
  }

  @Override
  public void collectIndexedItems(IndexedItemCollection indexedItems) {
    if (indexedItems.addField(this)) {
      holder.collectIndexedItems(indexedItems);
      type.collectIndexedItems(indexedItems);
      indexedItems.getRenamedName(this).collectIndexedItems(indexedItems);
    }
  }

  @Override
  public int getOffset(ObjectToOffsetMapping mapping) {
    return mapping.getOffsetFor(this);
  }

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

  @Override
  public DexField asDexField() {
    return this;
  }

  @Override
  public Iterable<DexType> getReferencedTypes() {
    return Collections.singleton(type);
  }

  @Override
  public int acceptCompareTo(DexField other, CompareToVisitor visitor) {
    return visitor.visitDexField(this, other);
  }

  @Override
  public boolean match(DexField field) {
    return field.name == name && field.type == type;
  }

  @Override
  public boolean match(DexEncodedField encodedField) {
    return match(encodedField.field);
  }

  public String qualifiedName() {
    return holder + "." + name;
  }

  @Override
  public String toSmaliString() {
    return holder.toSmaliString() + "->" + name + ":" + type.toSmaliString();
  }

  @Override
  public String toSourceString() {
    return type.toSourceString() + " " + holder.toSourceString() + "." + name.toSourceString();
  }

  public DexField withHolder(DexType holder, DexItemFactory dexItemFactory) {
    return dexItemFactory.createField(holder, type, name);
  }

  public DexField withName(DexString name, DexItemFactory dexItemFactory) {
    return dexItemFactory.createField(holder, type, name);
  }

  public DexField withType(DexType type, DexItemFactory dexItemFactory) {
    return dexItemFactory.createField(holder, type, name);
  }

  public FieldReference asFieldReference() {
    return Reference.field(
        Reference.classFromDescriptor(holder.toDescriptorString()),
        name.toString(),
        Reference.typeFromDescriptor(type.toDescriptorString()));
  }
}
