package net.openhft.chronicle.core.io;

import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.OS;
import org.junit.Test;

import java.util.concurrent.atomic.AtomicLong;

import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;

public class BackgroundResourceReleaserTest {
    static final AtomicLong closed = new AtomicLong();
    static final AtomicLong released = new AtomicLong();

    @Test
    public void testResourcesCleanedUp() {
        assumeTrue(BackgroundResourceReleaser.BG_RELEASER);
        int count = 10;
        for (int i = 1; i < count; i++) {
            new BGCloseable().close();
            new BGReferenceCounted().releaseLast();
        }
        assertEquals(1, closed.get(), 1);
        assertEquals(1, released.get(), 1);
        BGCloseable bgc = new BGCloseable();
        bgc.close();
        assertTrue(bgc.isClosing());
        assertFalse(bgc.isClosed());

        BGReferenceCounted bgr = new BGReferenceCounted();
        bgr.releaseLast();
        assertEquals(0, bgr.refCount());

        long start0 = System.currentTimeMillis();
        WaitingCloseable wc = new WaitingCloseable();
        new Thread(wc::close).start();
        wc.close();
        long time0 = System.currentTimeMillis() - start0;
        int error = Jvm.isArm() || OS.isWindows() ? 15 : 7;
        assertEquals(10 + error, time0, error);

        long start = System.currentTimeMillis();
        BackgroundResourceReleaser.releasePendingResources();
        long time = System.currentTimeMillis() - start;
        assertEquals(count * 10 + 5, time, 40);
        assertEquals(count, closed.get());
        assertEquals(count, released.get());
        AbstractCloseable.assertCloseablesClosed();
    }

    static class BGCloseable extends AbstractCloseable {
        @Override
        protected boolean shouldPerformCloseInBackground() {
            return true;
        }

        @Override
        protected void performClose() {
            closed.incrementAndGet();
            Jvm.pause(10);
        }
    }

    static class WaitingCloseable extends AbstractCloseable {
        @Override
        protected boolean shouldWaitForClosed() {
            return true;
        }

        @Override
        protected void performClose() {
            Jvm.pause(10);
        }
    }

    static class BGReferenceCounted extends AbstractReferenceCounted {
        @Override
        protected boolean performReleaseInBackground() {
            return true;
        }

        @Override
        protected void performRelease() {
            released.incrementAndGet();
            Jvm.pause(10);
        }
    }

}
@@ -306,31 +306,24 @@
 rTest %7B%0A    
-static 
 final Atomic
@@ -358,23 +358,16 @@
 ();%0A    
-static 
 final At
@@ -538,17 +538,17 @@
 count = 
-1
+2
 0;%0A     
@@ -1547,30 +1547,31 @@
       assert
-Equals
+Between
 (count * 10 
@@ -1571,22 +1571,17 @@
 t * 
-10 + 5
+4
 , time, 
 40);
@@ -1580,10 +1580,18 @@
 me, 
-40
+count * 11
 );%0A 
@@ -1740,31 +1740,263 @@
  %7D%0A%0A    
-static class BG
+private void assertBetween(long min, long actual, long max) %7B%0A        if (min %3C= actual && actual %3C= max)%0A            return;%0A        throw new AssertionError(%22Not in range %22 + min + %22 %3C= %22 + actual + %22 %3C= %22 + max);%0A    %7D%0A%0A    static class Waiting
 Closeabl
@@ -2079,31 +2079,20 @@
 ould
-Perf
+WaitF
 or
-m
 Close
-InBackgroun
 d() 
@@ -2191,46 +2191,8 @@
 ) %7B%0A
-            closed.incrementAndGet();%0A
     
@@ -2235,36 +2235,24 @@
  %7D%0A%0A    
-static class Waiting
+class BG
 Closeabl
@@ -2327,36 +2327,47 @@
 olean should
-WaitF
+Perf
 or
+m
 Close
+InBackgroun
 d() %7B%0A      
@@ -2446,32 +2446,70 @@
 erformClose() %7B%0A
+            closed.incrementAndGet();%0A
             Jvm.
@@ -2536,31 +2536,24 @@
 %0A    %7D%0A%0A    
-static 
 class BGRefe

Improve Azul Zing support, https://github.com/OpenHFT/OpenHFT/issues/47