package org.checkerframework.dataflow.expression;

import com.sun.tools.javac.code.Symbol;
import java.util.Objects;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.analysis.Store;
import org.checkerframework.dataflow.cfg.node.FieldAccessNode;
import org.checkerframework.javacutil.AnnotationProvider;
import org.checkerframework.javacutil.ElementUtils;
import org.checkerframework.javacutil.TypesUtils;

/**
 * A FieldAccess represents a field access. It does not represent a class literal such as {@code
 * SomeClass.class} or {@code int[].class}.
 */
public class FieldAccess extends JavaExpression {
  /** The receiver of the field access. */
  protected final JavaExpression receiver;
  /** The field being accessed. */
  protected final VariableElement field;

  /**
   * Returns the receiver.
   *
   * @return the receiver
   */
  public JavaExpression getReceiver() {
    return receiver;
  }

  /**
   * Returns the field.
   *
   * @return the field
   */
  public VariableElement getField() {
    return field;
  }

  /**
   * Create a {@code FieldAccess}.
   *
   * @param receiver receiver of the field access
   * @param node FieldAccessNode
   */
  public FieldAccess(JavaExpression receiver, FieldAccessNode node) {
    this(receiver, node.getType(), node.getElement());
  }

  /**
   * Create a {@code FieldAccess}.
   *
   * @param receiver receiver of the field access
   * @param fieldElement element of the field
   */
  public FieldAccess(JavaExpression receiver, VariableElement fieldElement) {
    this(receiver, fieldElement.asType(), fieldElement);
  }

  /**
   * Create a {@code FieldAccess}.
   *
   * @param receiver receiver of the field access
   * @param type type of the field
   * @param fieldElement element of the field
   */
  public FieldAccess(JavaExpression receiver, TypeMirror type, VariableElement fieldElement) {
    super(type);
    this.receiver = receiver;
    this.field = fieldElement;
    String fieldName = fieldElement.toString();
    if (fieldName.equals("class") || fieldName.equals("this")) {
      Error e =
          new Error(
              String.format(
                  "bad field name \"%s\" in new FieldAccess(%s, %s, %s)%n",
                  fieldName, receiver, type, fieldElement));
      e.printStackTrace(System.out);
      e.printStackTrace(System.err);
      throw e;
    }
  }

  public boolean isFinal() {
    return ElementUtils.isFinal(field);
  }

  public boolean isStatic() {
    return ElementUtils.isStatic(field);
  }

  @Override
  public boolean equals(@Nullable Object obj) {
    if (!(obj instanceof FieldAccess)) {
      return false;
    }
    FieldAccess fa = (FieldAccess) obj;
    return fa.getField().equals(getField()) && fa.getReceiver().equals(getReceiver());
  }

  @Override
  public int hashCode() {
    return Objects.hash(getField(), getReceiver());
  }

  @Override
  public boolean syntacticEquals(JavaExpression je) {
    if (!(je instanceof FieldAccess)) {
      return false;
    }
    FieldAccess other = (FieldAccess) je;
    return this.receiver.syntacticEquals(other.receiver) && this.field.equals(other.field);
  }

  @Override
  public boolean containsSyntacticEqualJavaExpression(JavaExpression other) {
    return syntacticEquals(other) || receiver.containsSyntacticEqualJavaExpression(other);
  }

  @Override
  public boolean containsModifiableAliasOf(Store<?> store, JavaExpression other) {
    return super.containsModifiableAliasOf(store, other)
        || receiver.containsModifiableAliasOf(store, other);
  }

  @Override
  public String toString() {
    if (receiver instanceof ClassName) {
      return receiver.getType() + "." + field;
    } else {
      return receiver + "." + field;
    }
  }

  @Override
  public String toStringDebug() {
    return String.format(
        "FieldAccess(type=%s, receiver=%s, field=%s [%s] [%s] owner=%s)",
        type,
        receiver.toStringDebug(),
        field,
        field.getClass().getSimpleName(),
        System.identityHashCode(field),
        ((Symbol) field).owner);
  }

  @Override
  public boolean containsOfClass(Class<? extends JavaExpression> clazz) {
    return getClass() == clazz || receiver.containsOfClass(clazz);
  }

  @Override
  public boolean isDeterministic(AnnotationProvider provider) {
    return receiver.isDeterministic(provider);
  }

  @Override
  public boolean isUnassignableByOtherCode() {
    return isFinal() && getReceiver().isUnassignableByOtherCode();
  }

  @Override
  public boolean isUnmodifiableByOtherCode() {
    return isUnassignableByOtherCode() && TypesUtils.isImmutableTypeInJdk(getReceiver().type);
  }

  @Override
  public <R, P> R accept(JavaExpressionVisitor<R, P> visitor, P p) {
    return visitor.visitFieldAccess(this, p);
  }
}
