package org.checkerframework.framework.util;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import javax.lang.model.element.AnnotationMirror;
import org.checkerframework.javacutil.AnnotationUtils;

/**
 * The Set interface defines many methods with respect to the equals method. This implementation of
 * Set violates those specifications, but fulfills the same property using {@link
 * AnnotationUtils#areSame} rather than equals.
 *
 * <p>For example, the specification for the contains(Object o) method says: "returns true if and
 * only if this collection contains at least one element e such that (o == null ? e == null :
 * o.equals(e))." The specification for {@link AnnotationMirrorSet#contains} is "returns true if and
 * only if this collection contains at least one element e such that (o == null ? e == null :
 * AnnotationUtils.areSame(o, e))".
 *
 * <p>AnnotationMirror is an interface and not all implementing classes provide a correct equals
 * method; therefore, the existing implementations of Set cannot be used.
 */
public class AnnotationMirrorSet implements Set<AnnotationMirror> {

  /** Backing set. */
  private Set<AnnotationMirror> shadowSet =
      new TreeSet<>(AnnotationUtils::compareAnnotationMirrors);

  /** Default constructor. */
  public AnnotationMirrorSet() {}

  public AnnotationMirrorSet(Collection<? extends AnnotationMirror> values) {
    this();
    this.addAll(values);
  }

  @Override
  public int size() {
    return shadowSet.size();
  }

  @Override
  public boolean isEmpty() {
    return shadowSet.isEmpty();
  }

  @Override
  public boolean contains(Object o) {
    return o instanceof AnnotationMirror
        && AnnotationUtils.containsSame(shadowSet, (AnnotationMirror) o);
  }

  @Override
  public Iterator<AnnotationMirror> iterator() {
    return shadowSet.iterator();
  }

  @Override
  public Object[] toArray() {
    return shadowSet.toArray();
  }

  @Override
  public <T> T[] toArray(T[] a) {
    return shadowSet.toArray(a);
  }

  @Override
  public boolean add(AnnotationMirror annotationMirror) {
    if (contains(annotationMirror)) {
      return false;
    }
    shadowSet.add(annotationMirror);
    return true;
  }

  @Override
  public boolean remove(Object o) {
    if (o instanceof AnnotationMirror) {
      AnnotationMirror found = AnnotationUtils.getSame(shadowSet, (AnnotationMirror) o);
      return found != null && shadowSet.remove(found);
    }
    return false;
  }

  @Override
  public boolean containsAll(Collection<?> c) {
    for (Object o : c) {
      if (!contains(o)) {
        return false;
      }
    }
    return true;
  }

  @Override
  public boolean addAll(Collection<? extends AnnotationMirror> c) {
    boolean result = true;
    for (AnnotationMirror a : c) {
      if (!add(a)) {
        result = false;
      }
    }
    return result;
  }

  @Override
  public boolean retainAll(Collection<?> c) {
    Set<AnnotationMirror> newSet = new TreeSet<>(AnnotationUtils::compareAnnotationMirrors);
    for (Object o : c) {
      if (contains(o)) {
        newSet.add((AnnotationMirror) o);
      }
    }
    if (newSet.size() != shadowSet.size()) {
      shadowSet = newSet;
      return true;
    }
    return false;
  }

  @Override
  public boolean removeAll(Collection<?> c) {
    boolean result = true;
    for (Object a : c) {
      if (!remove(a)) {
        result = false;
      }
    }
    return result;
  }

  @Override
  public void clear() {
    shadowSet.clear();
  }

  /**
   * Returns a new {@link AnnotationMirrorSet} that contains {@code value}.
   *
   * @param value AnnotationMirror to put in the set
   * @return a new {@link AnnotationMirrorSet} that contains {@code value}
   */
  public static AnnotationMirrorSet singleElementSet(AnnotationMirror value) {
    AnnotationMirrorSet newSet = new AnnotationMirrorSet();
    newSet.add(value);
    return newSet;
  }

  @Override
  public String toString() {
    return shadowSet.toString();
  }
}
