package org.checkerframework.dataflow.util;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.PolyNull;
import org.checkerframework.javacutil.BugInCF;

/**
 * Base class for arbitrary-size sets that very efficient (more efficient than HashSet) for 0 and 1
 * elements.
 *
 * <p>Does not support storing {@code null}.
 *
 * <p>This class exists because it has multiple subclasses (currently {@link MostlySingleton} and
 * {@link IdentityMostlySingleton}).
 */
public abstract class AbstractMostlySingleton<T extends Object> implements Set<T> {

  /** The possible states of this set. */
  public enum State {
    /** An empty set. */
    EMPTY,
    /** A singleton set. */
    SINGLETON,
    /** A set of arbitrary size. */
    ANY
  }

  /** The current state. */
  protected State state;
  /** The current value, non-null when the state is SINGLETON. */
  protected @Nullable T value;
  /** The wrapped set, non-null when the state is ANY. */
  protected @Nullable Set<T> set;

  /** Create an AbstractMostlySingleton. */
  protected AbstractMostlySingleton(State s) {
    this.state = s;
    this.value = null;
  }

  /** Create an AbstractMostlySingleton. */
  protected AbstractMostlySingleton(State s, T v) {
    this.state = s;
    this.value = v;
  }

  @Override
  public int size() {
    switch (state) {
      case EMPTY:
        return 0;
      case SINGLETON:
        return 1;
      case ANY:
        assert set != null : "@AssumeAssertion(nullness): set initialized before";
        return set.size();
      default:
        throw new BugInCF("Unhandled state " + state);
    }
  }

  @Override
  public boolean isEmpty() {
    return size() == 0;
  }

  @Override
  public Iterator<T> iterator() {
    switch (state) {
      case EMPTY:
        return Collections.emptyIterator();
      case SINGLETON:
        return new Iterator<T>() {
          private boolean hasNext = true;

          @Override
          public boolean hasNext() {
            return hasNext;
          }

          @Override
          public T next() {
            if (hasNext) {
              hasNext = false;
              assert value != null : "@AssumeAssertion(nullness): previous add is non-null";
              return value;
            }
            throw new NoSuchElementException();
          }

          @Override
          public void remove() {
            state = State.EMPTY;
            value = null;
          }
        };
      case ANY:
        assert set != null : "@AssumeAssertion(nullness): set initialized before";
        return set.iterator();
      default:
        throw new BugInCF("Unhandled state " + state);
    }
  }

  @Override
  public String toString() {
    switch (state) {
      case EMPTY:
        return "[]";
      case SINGLETON:
        return "[" + value + "]";
      case ANY:
        assert set != null : "@AssumeAssertion(nullness): set initialized before";
        return set.toString();
      default:
        throw new BugInCF("Unhandled state " + state);
    }
  }

  @Override
  public boolean addAll(Collection<? extends T> c) {
    boolean res = false;
    for (T elem : c) {
      res |= add(elem);
    }
    return res;
  }

  @Override
  public Object[] toArray() {
    throw new UnsupportedOperationException();
  }

  @Override
  public <S> @Nullable S[] toArray(@PolyNull S[] a) {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean remove(@Nullable Object o) {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean containsAll(Collection<?> c) {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean retainAll(Collection<?> c) {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean removeAll(Collection<?> c) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void clear() {
    throw new UnsupportedOperationException();
  }
}
