import java.lang.reflect.Field;
import org.checkerframework.checker.testchecker.wholeprograminference.qual.Parent;
import org.checkerframework.checker.testchecker.wholeprograminference.qual.Sibling1;
import org.checkerframework.checker.testchecker.wholeprograminference.qual.Sibling2;
import org.checkerframework.checker.testchecker.wholeprograminference.qual.ToIgnore;
import org.checkerframework.checker.testchecker.wholeprograminference.qual.Top;
import org.checkerframework.checker.testchecker.wholeprograminference.qual.WholeProgramInferenceBottom;
import org.checkerframework.framework.qual.IgnoreInWholeProgramInference;

/**
 * This file contains expected errors that should exist even after the jaif type inference occurs.
 */
public class ExpectedErrors {

  // Case where the declared type is a supertype of the refined type.
  private @Top int privateDeclaredField;
  public @Top int publicDeclaredField;

  // The type of both privateDeclaredField and publicDeclaredField are
  // not refined to @WholeProgramInferenceBottom.
  void assignFieldsToSibling1() {
    privateDeclaredField = getSibling1();
    publicDeclaredField = getSibling1();
  }

  void testFields() {
    // :: warning: (argument)
    expectsSibling1(privateDeclaredField);
    // :: warning: (argument)
    expectsSibling1(publicDeclaredField);
  }

  // Case where the declared type is a subtype of the refined type.
  private @WholeProgramInferenceBottom int privateDeclaredField2;
  public @WholeProgramInferenceBottom int publicDeclaredField2;

  // The refinement cannot happen and an assignemnt type incompatible error occurs.
  void assignFieldsToTop() {
    // :: warning: (assignment)
    privateDeclaredField2 = getTop();
    // :: warning: (assignment)
    publicDeclaredField2 = getTop();
  }

  // No errors should be issued below:
  void assignFieldsToBot() {
    privateDeclaredField2 = getBottom();
    publicDeclaredField2 = getBottom();
  }

  // Testing that the types above were not widened.
  void testFields2() {
    expectsBottom(privateDeclaredField2);
    expectsBottom(publicDeclaredField2);
  }

  // LUB TEST
  // The default type for fields is @Top.
  private static int lubPrivateField;
  public static int lubPublicField;

  void assignLubFieldsToSibling1() {
    lubPrivateField = getSibling1();
    lubPublicField = getSibling1();
  }

  static {
    lubPrivateField = getSibling2();
    lubPublicField = getSibling2();
  }

  void testLUBFields1() {
    // :: warning: (argument)
    expectsSibling1(lubPrivateField);
    // :: warning: (argument)
    expectsSibling1(lubPublicField);
  }

  void testLUBFields2() {
    // :: warning: (argument)
    expectsSibling2(lubPrivateField);
    // :: warning: (argument)
    expectsSibling2(lubPublicField);
  }

  private static boolean bool = false;

  public static int lubTest() {
    if (bool) {
      return (@Sibling1 int) 0;
    } else {
      return (@Sibling2 int) 0;
    }
  }

  public @Sibling1 int getSibling1Wrong() {
    int x = lubTest();
    // :: warning: (return)
    return x;
  }

  public @Sibling2 int getSibling2Wrong() {
    int x = lubTest();
    // :: warning: (return)
    return x;
  }

  void expectsSibling1(@Sibling1 int t) {}

  void expectsSibling2(@Sibling2 int t) {}

  void expectsBottom(@WholeProgramInferenceBottom int t) {}

  void expectsBottom(@WholeProgramInferenceBottom String t) {}

  void expectsTop(@Top int t) {}

  void expectsParent(@Parent int t) {}

  static @Sibling1 int getSibling1() {
    return 0;
  }

  static @Sibling2 int getSibling2() {
    return 0;
  }

  @WholeProgramInferenceBottom int getBottom() {
    return 0;
  }

  @Top int getTop() {
    return 0;
  }

  // Method Field.setBoolean != ExpectedErrors.setBoolean.
  // No refinement should happen.
  void test(Field f) throws Exception {
    f.setBoolean(null, false);
  }

  void setBoolean(Object o, boolean b) {
    // :: warning: (assignment)
    @WholeProgramInferenceBottom Object bot = o;
  }

  public class SuppressWarningsTest {
    // Tests that whole-program inference in a @SuppressWarnings block is ignored.
    private int i;
    private int i2;

    @SuppressWarnings("all")
    public void suppressWarningsTest() {
      i = (@Sibling1 int) 0;
      i2 = getSibling1();
    }

    public void suppressWarningsTest2() {
      SuppressWarningsInner.i = (@Sibling1 int) 0;
      SuppressWarningsInner.i2 = getSibling1();
    }

    public void suppressWarningsValidation() {
      // :: warning: (argument)
      expectsSibling1(i);
      // :: warning: (argument)
      expectsSibling1(i2);
      // :: warning: (argument)
      expectsSibling1(SuppressWarningsInner.i);
      // :: warning: (argument)
      expectsSibling1(SuppressWarningsInner.i2);
      // :: warning: (argument)
      expectsSibling1(suppressWarningsMethodReturn());

      suppressWarningsMethodParams(getSibling1());
    }

    @SuppressWarnings("all")
    public int suppressWarningsMethodReturn() {
      return getSibling1();
    }

    // It is problematic to automatically test whole-program inference for method params when
    // suppressing warnings.
    // Since we must use @SuppressWarnings() for the method, we won't be able to catch any error
    // inside the method body.  Verified manually that in the "annotated" folder param's type wasn't
    // updated.
    @SuppressWarnings("all")
    public void suppressWarningsMethodParams(int param) {}
  }

  @SuppressWarnings("all")
  static class SuppressWarningsInner {
    public static int i;
    public static int i2;
  }

  class NullTest {
    // The default type for fields is @DefaultType.
    private String privateField;
    public String publicField;

    // The types of both fields are not refined to @WholeProgramInferenceBottom, as whole-program
    // inference never performs refinement in the presence of the null literal.
    @SuppressWarnings("value")
    void assignFieldsToBottom() {
      privateField = null;
      publicField = null;
    }

    // Testing the refinement above.
    void testFields() {
      // :: warning: (argument)
      expectsBottom(privateField);
      // :: warning: (argument)
      expectsBottom(publicField);
    }
  }

  class IgnoreMetaAnnotationTest2 {
    @ToIgnore int field;
    @IgnoreInWholeProgramInference int field2;

    void foo() {
      field = getSibling1();
      field2 = getSibling1();
    }

    void test() {
      // :: warning: (argument)
      expectsSibling1(field);
      // :: warning: (argument)
      expectsSibling1(field2);
    }
  }

  class AssignParam {
    public void f(@WholeProgramInferenceBottom Object param) {
      // :: warning: assignment
      param = ((@Top Object) null);
    }
  }
}
