import java.util.HashMap;
import java.util.Map;
import org.checkerframework.checker.interning.qual.InternMethod;
import org.checkerframework.checker.interning.qual.Interned;

public @Interned class InternedClass2 {
  private final int i;
  // @UnknownInterned is the default annotation on constructor results even for @Interned classes.
  private InternedClass2(int i) {
    // Type of "this" inside a constructor of an @Interned class is @UnknownInterned.
    // :: error: (assignment)
    @Interned InternedClass2 that = this;
    this.i = i;
  }

  InternedClass2 factory(int i) {
    // :: error: (interned.object.creation) :: error: (method.invocation)
    new InternedClass2(i).someMethod(); // error, call to constructor on for @Interned class.
    (new InternedClass2(i)).intern(); // ok, call to constructor receiver to @InternMethod
    ((((new InternedClass2(i))))).intern(); // ok, call to constructor receiver to @InternMethod
    return new InternedClass2(i).intern(); // ok, call to constructor receiver to @InternMethod
  }

  void someMethod() {
    // Type of "this" inside a method (not marked @InternedMethod) is @Interned,
    // assuming the method is declared in an @Interned class.
    @Interned InternedClass2 that = this; // ok
  }

  private static Map<Integer, InternedClass2> pool = new HashMap<>();

  @InternMethod
  public InternedClass2 intern() {
    // Type of "this" inside an @InternMethod is @UnknownInterned
    // :: error: (assignment)
    @Interned InternedClass2 that = this;
    if (!pool.containsKey(this.i)) {
      // The above check proves "this" is interned.
      @SuppressWarnings("interning:assignment")
      @Interned InternedClass2 internedThis = this;
      pool.put(this.i, internedThis);
    }
    return pool.get(this.i);
  }

  @Override // ok, no override invalid receiver error is issued.
  public String toString() {
    @Interned InternedClass2 that = this; // ok
    return super.toString();
  }

  @Override
  public boolean equals(Object object) {
    if (this == object) {
      return true;
    }
    if (object == null || getClass() != object.getClass()) {
      return false;
    }

    InternedClass2 that = (InternedClass2) object;

    return i == that.i;
  }

  @Override
  public int hashCode() {
    return i;
  }

  public boolean hasNodeOfType(Class<?> type) {
    if (type == this.getClass()) {
      return true;
    }
    return false;
  }
}
