/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import junit.framework.TestCase;

/** @author Michał Pociecha-Łoś */
public class RetentionTest extends TestCase {
  public void testArrayAccess() {
    Object[] array = new Object[1];
    array[0] = new Object();
    runInNewThread(
        () -> {
          Object object = array[0];
          runInNewThread(
              () -> {
                array[0] = null;
              });
          object.hashCode(); // should not crash
        });
  }

  // TODO(micapolos): Uncomment once fixed.
  // public void testFieldAccess() {
  //   Ref ref = new Ref();
  //   ref.object = new Object();
  //   runInNewThread(
  //       () -> {
  //         Object object = ref.object;
  //         runInNewThread(
  //             () -> {
  //               ref.object = null;
  //             });
  //         object.hashCode(); // should not crash
  //       });
  // }

  // TODO(micapolos): Uncomment once fixed.
  // public void testFieldGetter() {
  //   Ref ref = new Ref();
  //   ref.object = new Object();
  //   runInNewThread(
  //       () -> {
  //         Object object = ref.get();
  //         runInNewThread(
  //             () -> {
  //               ref.object = null;
  //             });
  //         object.hashCode(); // should not crash
  //       });
  // }

  // TODO(micapolos): Uncomment once fixed.
  // public void testAutoreleasePoolInForLoop() {
  //   Object object = null;
  //   for (@AutoreleasePool int i = 0; i < 1; i++) {
  //     object = new Object();
  //   }
  //   object.hashCode(); // should not crash
  // }

  static void runInNewThread(Runnable runnable) {
    Thread thread = new Thread(runnable);
    thread.start();
    try {
      thread.join();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new RuntimeException(e);
    }
  }

  static class Ref {
    Object object;

    Object get() {
      return object;
    }
  }
}

@@ -552,16 +552,63 @@
 e.%0A */%0A%0A
+import com.google.j2objc.util.AutoreleasePool;%0A
 import j
@@ -792,75 +792,92 @@
     
-array%5B0%5D = new Object();%0A    runInNewThread(%0A        () -%3E %7B%0A      
+AutoreleasePool.run(%0A        () -%3E %7B%0A          array%5B0%5D = new Object();%0A        %7D);%0A
     
@@ -910,36 +910,29 @@
     
-      runInNewThread(%0A      
+AutoreleasePool.run(%0A
     
@@ -949,30 +949,24 @@
 %7B%0A          
- 
-     
 array%5B0%5D = n
@@ -982,24 +982,12 @@
     
-      %7D);%0A      
+%7D);%0A
     
@@ -1025,28 +1025,16 @@
 t crash%0A
-        %7D);%0A
   %7D%0A%0A  /
@@ -1150,164 +1150,145 @@
 /   
-ref.object = new Object();%0A  //   runInNewThread(%0A  //       () -%3E %7B%0A  //         Object object = ref.object;%0A  //         runInNewThread(%0A  //             
+AutoreleasePool.run(() -%3E %7B%0A  //     ref.object = new Object();%0A  //   %7D);%0A  //   Object object = ref.object;%0A  //   AutoreleasePool.run(
 () -
@@ -1291,34 +1291,24 @@
 () -%3E %7B%0A  //
-          
      ref.obj
@@ -1319,34 +1319,24 @@
 = null;%0A  //
-          
    %7D);%0A  // 
@@ -1326,38 +1326,32 @@
 %0A  //   %7D);%0A  //
-      
    object.hashCo
@@ -1372,39 +1372,24 @@
 d not crash%0A
-  //       %7D);%0A
   // %7D%0A%0A  //
@@ -1504,163 +1504,144 @@
 /   
-ref.object = new Object();%0A  //   runInNewThread(%0A  //       () -%3E %7B%0A  //         Object object = ref.get();%0A  //         runInNewThread(%0A  //             
+AutoreleasePool.run(() -%3E %7B%0A  //     ref.object = new Object();%0A  //   %7D);%0A  //   Object object = ref.get();%0A  //   AutoreleasePool.run(
 () -
@@ -1648,26 +1648,16 @@
 %3E %7B%0A  //
-          
      ref
@@ -1676,26 +1676,16 @@
 ll;%0A  //
-          
    %7D);%0A 
@@ -1687,22 +1687,16 @@
 %7D);%0A  //
-      
    objec
@@ -1733,23 +1733,8 @@
 ash%0A
-  //       %7D);%0A
   //
@@ -2013,280 +2013,8 @@
  %7D%0A%0A
-  static void runInNewThread(Runnable runnable) %7B%0A    Thread thread = new Thread(runnable);%0A    thread.start();%0A    try %7B%0A      thread.join();%0A    %7D catch (InterruptedException e) %7B%0A      Thread.currentThread().interrupt();%0A      throw new RuntimeException(e);%0A    %7D%0A  %7D%0A%0A
   st

Simplify RetentionTest to use autorelease pools instead of threads.