import java.util.concurrent.locks.ReentrantLock;
import org.checkerframework.checker.lock.qual.GuardedBy;
import org.checkerframework.checker.lock.qual.GuardedByUnknown;
import org.checkerframework.checker.lock.qual.MayReleaseLocks;
import org.checkerframework.dataflow.qual.Deterministic;
import org.checkerframework.dataflow.qual.Pure;

public class LockExpressionIsFinal {

  class MyClass {
    Object field = new Object();
  }

  class C1 {
    final C1 field = new C1(); // Infinite loop. This code is not meant to be executed, only type
    // checked.
    C1 field2;

    @Deterministic
    C1 getFieldDeterministic() {
      return field;
    }

    @Pure
    C1 getFieldPure(Object param1, Object param2) {
      return field;
    }

    @Pure
    C1 getFieldPure2() {
      return field;
    }

    C1 getField() {
      return field;
    }
  }

  final C1 c1 = new C1();

  // Analogous to testExplicitLockExpressionIsFinal and testGuardedByExpressionIsFinal, but for
  // monitor locks acquired in synchronized blocks.
  void testSynchronizedExpressionIsFinal(boolean b) {
    synchronized (c1) {
    }

    Object o1 = new Object(); // o1 is effectively final - it is never reassigned
    Object o2 = new Object(); // o2 is reassigned later - it is not effectively final
    synchronized (o1) {
    }
    // :: error: (lock.expression.not.final)
    synchronized (o2) {
    }

    o2 = new Object(); // Reassignment that makes o2 not have been effectively final earlier.

    // Tests that package names are considered final.
    synchronized (java.lang.String.class) {
    }

    // Test a tree that is not supported by LockVisitor.ensureExpressionIsEffectivelyFinal
    // :: error: (lock.expression.possibly.not.final)
    synchronized (c1.getFieldPure(b ? c1 : o1, c1)) {
    }

    synchronized (
        c1.field.field.field.getFieldPure(
                c1.field, c1.getFieldDeterministic().getFieldPure(c1, c1.field))
            .field) {
    }

    // The following negative test cases are the same as the one above but with one modification
    // in each.

    synchronized (
        // :: error: (lock.expression.not.final)
        c1.field.field2.field.getFieldPure(
                c1.field, c1.getFieldDeterministic().getFieldPure(c1, c1.field))
            .field) {
    }
    synchronized (
        c1.field.field.field.getFieldPure(
                // :: error: (lock.expression.not.final)
                c1.field, c1.getField().getFieldPure(c1, c1.field))
            .field) {
    }
  }

  class C2 extends ReentrantLock {
    final C2 field =
        new C2(); // Infinite loop. The code is not meant to be executed, only type-checked.
    C2 field2;

    @Deterministic
    C2 getFieldDeterministic() {
      return field;
    }

    @Pure
    C2 getFieldPure(Object param1, Object param2) {
      return field;
    }

    C2 getField() {
      return field;
    }
  }

  final C2 c2 = new C2();

  // Analogous to testSynchronizedExpressionIsFinal and testGuardedByExpressionIsFinal, but for
  // explicit locks.
  @MayReleaseLocks
  void testExplicitLockExpressionIsFinal(boolean b) {
    c2.lock();

    ReentrantLock rl1 = new ReentrantLock(); // rl1 is effectively final - it is never reassigned
    ReentrantLock rl2 =
        new ReentrantLock(); // rl2 is reassigned later - it is not effectively final
    rl1.lock();
    rl1.unlock();
    // :: error: (lock.expression.not.final)
    rl2.lock();
    // :: error: (lock.expression.not.final)
    rl2.unlock();

    rl2 = new ReentrantLock(); // Reassignment that makes rl2 not have been effectively final
    // earlier.

    // Test a tree that is not supported by LockVisitor.ensureExpressionIsEffectivelyFinal
    // :: error: (lock.expression.possibly.not.final)
    c2.getFieldPure(b ? c2 : rl1, c2).lock();
    // :: error: (lock.expression.possibly.not.final)
    c2.getFieldPure(b ? c2 : rl1, c2).unlock();

    c2.field
        .field
        .field
        .getFieldPure(c2.field, c2.getFieldDeterministic().getFieldPure(c2, c2.field))
        .field
        .lock();
    c2.field
        .field
        .field
        .getFieldPure(c2.field, c2.getFieldDeterministic().getFieldPure(c2, c2.field))
        .field
        .unlock();

    // The following negative test cases are the same as the one above but with one modification
    // in each.

    c2.field
        // :: error: (lock.expression.not.final)
        .field2
        .field
        .getFieldPure(c2.field, c2.getFieldDeterministic().getFieldPure(c2, c2.field))
        .field
        .lock();
    c2.field
        // :: error: (lock.expression.not.final)
        .field2
        .field
        .getFieldPure(c2.field, c2.getFieldDeterministic().getFieldPure(c2, c2.field))
        .field
        .unlock();

    c2.field
        .field
        .field
        // :: error: (lock.expression.not.final)
        .getFieldPure(c2.field, c2.getField().getFieldPure(c2, c2.field))
        .field
        .lock();
    c2.field
        .field
        .field
        // :: error: (lock.expression.not.final)
        .getFieldPure(c2.field, c2.getField().getFieldPure(c2, c2.field))
        .field
        .unlock();
  }

  // Analogous to testSynchronizedExpressionIsFinal and testExplicitLockExpressionIsFinal, but for
  // expressions in @GuardedBy annotations.
  void testGuardedByExpressionIsFinal() {
    @GuardedBy("c1") Object guarded1;

    final Object o1 = new Object();
    Object o2 = new Object();
    // reassign so it's not effectively final
    o2 = new Object();

    @GuardedBy("o1") Object guarded2 = new Object();
    // :: error: (lock.expression.not.final)
    @GuardedBy("o2") Object guarded3 = new Object();

    // Test expressions that are not supported by LockVisitor.ensureExpressionIsEffectivelyFinal
    @GuardedBy("java.lang.String.class") Object guarded4;
    // :: error: (expression.unparsable)
    @GuardedBy("c1.getFieldPure(b ? c1 : o1, c1)") Object guarded5;

    @GuardedBy(
        "c1.field.field.field.getFieldPure"
            + "(c1.field, c1.getFieldDeterministic().getFieldPure(c1, c1.field)).field")
    Object guarded6;

    @GuardedBy("c1.field.field.field.getFieldPure2().getFieldDeterministic().field") Object guarded7;

    // The following negative test cases are the same as the one above but with one modification
    // in each.

    // :: error: (lock.expression.not.final)
    @GuardedBy("c1.field.field2.field.getFieldPure2().getFieldDeterministic().field") Object guarded8;
    // :: error: (lock.expression.not.final)
    @GuardedBy("c1.field.field.field.getField().getFieldDeterministic().field") Object guarded9;

    // Additional test cases to test that method parameters (in this case the parameters to
    // getFieldPure) are parsed.
    @GuardedBy("c1.field.field.field.getFieldPure(c1, c1).getFieldDeterministic().field") Object guarded10;
    @GuardedBy("c1.field.field.field.getFieldPure(c1, o1).getFieldDeterministic().field") Object guarded11;
    // :: error: (lock.expression.not.final)
    @GuardedBy("c1.field.field.field.getFieldPure(c1, o2).getFieldDeterministic().field") Object guarded12;

    // Test that @GuardedBy annotations on various tree kinds inside a method are visited

    Object guarded13 = (@GuardedBy("o1") Object) guarded2;
    // :: error: (lock.expression.not.final)
    Object guarded14 = (@GuardedBy("o2") Object) guarded3;

    Object guarded15[] = new @GuardedBy("o1") MyClass[3];
    // :: error: (lock.expression.not.final)
    Object guarded16[] = new @GuardedBy("o2") MyClass[3];

    // Tests that the location of the @GB annotation inside a VariableTree does not matter (i.e.
    // it does not need to be the leftmost subtree).
    Object guarded17 @GuardedBy("o1") [];
    // :: error: (lock.expression.not.final)
    Object guarded18 @GuardedBy("o2") [];

    @GuardedBy("o1") Object guarded19[];
    // :: error: (lock.expression.not.final)
    @GuardedBy("o2") Object guarded20[];

    MyParameterizedClass1<@GuardedBy("o1") Object> m1;
    // :: error: (lock.expression.not.final)
    MyParameterizedClass1<@GuardedBy("o2") Object> m2;

    boolean b = c1 instanceof @GuardedBy("o1") Object;
    // instanceof expression have not effect on the type.
    // // :: error: (lock.expression.not.final)
    b = c1 instanceof @GuardedBy("o2") Object;

    // Additional tests just outside of this method below:
  }

  // Test that @GuardedBy annotations on various tree kinds outside a method are visited

  // Test that @GuardedBy annotations on method return types are visited. No need to test method
  // receivers and parameters as they are covered by tests above that visit VariableTree.

  final Object finalField = new Object();
  Object nonFinalField = new Object();

  @GuardedBy("finalField") Object testGuardedByExprIsFinal1() {
    return null;
  }

  // :: error: (lock.expression.not.final)
  @GuardedBy("nonFinalField") Object testGuardedByExprIsFinal2() {
    return null;
  }

  <T extends @GuardedBy("finalField") Object> T myMethodThatReturnsT_1(T t) {
    return t;
  }

  // :: error: (lock.expression.not.final)
  <T extends @GuardedBy("nonFinalField") Object> T myMethodThatReturnsT_2(T t) {
    return t;
  }

  class MyParameterizedClass1<T extends @GuardedByUnknown Object> {}

  MyParameterizedClass1<? super @GuardedBy("finalField") Object> m1;
  // :: error: (lock.expression.not.final)
  MyParameterizedClass1<? super @GuardedBy("nonFinalField") Object> m2;

  MyParameterizedClass1<? extends @GuardedBy("finalField") Object> m3;
  // :: error: (lock.expression.not.final)
  MyParameterizedClass1<? extends @GuardedBy("nonFinalField") Object> m4;

  class MyClassContainingALock {
    final ReentrantLock finalLock = new ReentrantLock();
    ReentrantLock nonFinalLock = new ReentrantLock();
    Object field;
  }

  void testItselfFinalLock() {
    final @GuardedBy("<self>.finalLock") MyClassContainingALock m = new MyClassContainingALock();
    // :: error: (lock.not.held)
    m.field = new Object();
    // Ignore this error: it is expected that an error will be issued for dereferencing 'm' in
    // order to take the 'm.finalLock' lock.  Typically, the Lock Checker does not support an
    // object being guarded by one of its fields, but this is sometimes done in user code with a
    // ReentrantLock field guarding its containing object. This unfortunately makes it a bit
    // difficult for users since they have to add a @SuppressWarnings for this call while still
    // making sure that warnings for other dereferences are not suppressed.
    // :: error: (lock.not.held)
    m.finalLock.lock();
    m.field = new Object();
  }

  void testItselfNonFinalLock() {
    final @GuardedBy("<self>.nonFinalLock") MyClassContainingALock m = new MyClassContainingALock();
    // ::error: (lock.not.held) :: error: (lock.expression.not.final)
    m.field = new Object();
    // ::error: (lock.not.held) :: error: (lock.expression.not.final)
    m.nonFinalLock.lock();
    // :: error: (lock.expression.not.final)
    m.field = new Object();
  }
}
