import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.checkerframework.framework.testchecker.h1h2checker.quals.*;

public class InferTypeArgsPolyChecker<OUTER_SCOPE_TV> {
  // ----------------------------------------------------------
  // Test Case - A
  <A> A methodA(@H2Top A a1, @H2Top A a2) {
    return null;
  }

  void contextA(@H1S1 @H2Bot String str, @H1Bot @H2Bot List<@H1S2 String> s) {
    @H2Bot Object a = methodA(str, s);
    @H1Top @H2Bot Object aTester = a;
  }

  // ----------------------------------------------------------
  // Test Case - B
  <B> B methodB(List<@H2S2 B> b1, List<@H1S2 B> b2) {
    return null;
  }

  void contextB(List<@H1S1 @H2S2 String> l1, List<@H1S2 @H2S1 String> l2) {
    @H1S1 @H2S1 String str = methodB(l1, l2);
  }

  // ----------------------------------------------------------
  // Test Case - C
  <C extends List<? extends Object>> C methodC(C c1, C c2) {
    return null;
  }

  void contextC(List<@H1S1 @H2S2 ? extends @H1S1 @H2S2 String> l1, List<@H1S1 @H2S2 String> l2) {
    List<@H1S1 @H2S2 ?> str = methodC(l1, l2);
  }

  // ----------------------------------------------------------
  // Test Case - D

  <D extends OUTER_SCOPE_TV, DD> D methodD(D d1, D d2, DD dd) {
    return null;
  }

  <D extends OUTER_SCOPE_TV, DD> DD methodD2(D d1, D d2, DD dd) {
    return null;
  }

  void contextD(OUTER_SCOPE_TV os1, @H1S1 @H2S1 OUTER_SCOPE_TV os2) {
    OUTER_SCOPE_TV osNaked1 = methodD(os1, os1, os2);

    // So for the next failure we correctly infer that for methodD to take both os1 and os2 as
    // arguments D must be @H1Top @H2Top OUTER_SCOPE_TV.  However, the UPPER_BOUND of D is
    // <@H1Bottom @H2Bottom OUTER_SCOPE_TV extends @H1Top @H2Top Object> notice that our
    // inferred type for D is above this bound.
    //
    // A similar, more useful example in the Nullness type system would be:
    /*
       class Gen<OUTER> {
          public List<OUTER> listo;

          <T extends OUTER> void addToListo(T t1, T T2) {
              listo.add(t1);
              listo.add(t2);
          }

          void launder(@NonNull OUTER arg1, @Nullable OUTER arg2) {
              addToListo(arg1, arg2); // T is inferred to be <@Nullable OUTER>
                                      // if we did not mark this as type.argument
                                      // then we would have no idea that in the last
                                      // line of this example we are putting a null value into
                                      // a List of @NonNull Strings
          }

       }

       Gen<@NonNull String> g = ...;
       g.listo = new ArrayList<@NonNull String>();
       g.launder("", null);    // during this method call null would be added to g.listo
    */
    // :: error: (type.argument)
    OUTER_SCOPE_TV osNaked2 = methodD(os1, os2, "");

    // :: error: (type.argument)
    OUTER_SCOPE_TV osAnnoed = methodD(os2, os2, "");

    // :: error: (type.argument)
    String str = methodD2(os2, os1, "");
    OUTER_SCOPE_TV osNaked3 = methodD2(os1, os1, os2);
  }

  // ----------------------------------------------------------
  // Test Case - E
  <E> E methodE(E e1, E[] aos2) {
    return null;
  } // pass an array to one of these to cover A2FReducer.visitArray_Typevar

  void contextE(String[] strArr, String[][] strArrArr, OUTER_SCOPE_TV os, OUTER_SCOPE_TV[] aos) {
    String[] strArrLocal = methodE(strArr, strArrArr);
    OUTER_SCOPE_TV osLocal = methodE(os, aos);
  }

  // ----------------------------------------------------------
  // Test Case - C
  <F> List<? super F> methodF(List<? extends F> lExtF, List<? super F> lSupF) {
    return null;
  }

  void contextF(
      List<@H1Bot @H2Bot ? extends @H1Top @H2S1 String> l1,
      List<? super @H1S1 @H2S2 String> l2,
      List<@H1S1 @H2S2 ? extends @H1Top @H2Top String> l3) {

    // :: error: (argument)
    List<? super @H1Bot @H2Bot String> lstr1 = methodF(l1, l2);

    // :: error: (argument)
    List<? super @H1Top @H2S2 String> lstr2 = methodF(l3, l2);
  }

  <G extends List<H>, H extends List<G>> List<H> methodG(G g1, G G2) {
    return null;
  }

  class NodeList extends ArrayList<@H1Top @H2Top NodeList> {}

  void contextG(NodeList l1, NodeList l2) {
    List<@H1Top @H2Top NodeList> a = methodG(l1, l2);
  }

  // add test case for Array<String> vs. String[]
  // add test case of E extends F, F extends G, H extends List<? super E> and other craziness

  <M, N extends M> Map<M, N> method() {
    return null;
  }

  void contextMN() {

    // so I am not exactly sure how to create a meaningful test for this case
    // what occurs is the SubtypeSolver.propagateGlbs forces N to be a subtype of M
    // and it works (at least while I was debugging) but I don't know how to create
    // a check that fails or succeeds because of this
    Map<? super @H1S1 @H2S2 CharSequence, @H1Top @H2Top ? super String> mnl = method();
  }

  //    class Pair<PONE,PTWO> {
  //        PONE _1;
  //        PTWO _2;
  //    }

  <O extends P, P> @H1Top @H2Top P methodOP(@H1Top @H2Top P p, O o) {
    return null;
  }

  void contextOP(@H1S1 @H2S1 String s1, @H1Bot @H2Bot String s2) {
    // This test is actually here to test that the constraint P :> O is implied on p
    // :: error: (assignment)
    @H1Bot @H2Bot String loc = methodOP(s1, s2);
  }

  //    class Triplet<L,M,N> {
  //        L l;
  //        M m;
  //        N n;
  //    }
  //
  //    <X extends Y, Y extends Z, Z> Triplet<X,Y,Z> methodXYZ() {
  //        return null;
  //    }
  //
  //    void contextXYZ() {
  //        Triplet<@H1S>
  //    }
}
