package com.notnoop.apns.internal;

import static org.junit.Assert.*;

import java.util.concurrent.Semaphore;

import javax.net.SocketFactory;

import org.junit.Test;
import static org.mockito.Mockito.*;

import com.notnoop.apns.ApnsNotification;
import com.notnoop.apns.ApnsService;

public class QueuedApnsServiceTest extends ApnsServiceImplTest{

    @Test(expected=IllegalStateException.class)
    public void sendWithoutStarting() {
        QueuedApnsService service = new QueuedApnsService(null);
        service.push(notification);
    }

    @Test
    public void dontBlock() {
        final int delay = 10000;
        ConnectionStub connection = spy(new ConnectionStub(delay, 2));
        QueuedApnsService queued =
            new QueuedApnsService(new ApnsServiceImpl(connection, null));
        queued.start();
        long time1 = System.currentTimeMillis();
        queued.push(notification);
        queued.push(notification);
        long time2 = System.currentTimeMillis();
        assertTrue("queued.push() blocks", (time2 - time1) < delay);

        connection.interrupt();
        connection.semaphor.acquireUninterruptibly();
        verify(connection, times(2)).sendMessage(notification);

        queued.stop();
    }

    protected ApnsService newService(ApnsConnection connection, ApnsFeedbackConnection feedback) {
        ApnsService service = new ApnsServiceImpl(connection, null);
        ApnsService queued = new QueuedApnsService(service);
        queued.start();
        return queued;
    }

    static class ConnectionStub extends ApnsConnection {
        Semaphore semaphor;
        int delay;

        public ConnectionStub(int delay, int expectedCalls) {
            super(null, null, 80);
            this.semaphor = new Semaphore(1-expectedCalls);
            this.delay = delay;
        }

        volatile boolean stop;

        protected synchronized void sendMessage(ApnsNotification m) {
            long time = System.currentTimeMillis();
            while (!stop && (System.currentTimeMillis() < time));
            semaphor.release();
        }

        protected void interrupt() {
            stop = true;
        }

    }
}

@@ -108,41 +108,8 @@
 e;%0A%0A
-import javax.net.SocketFactory;%0A%0A
 impo
@@ -127,16 +127,16 @@
 t.Test;%0A
+
 import s
@@ -284,35 +284,8 @@
 est 
-extends ApnsServiceImplTest
 %7B%0A%0A 
@@ -432,24 +432,24 @@
 vice(null);%0A
-
         serv
@@ -475,24 +475,432 @@
 on);%0A    %7D%0A%0A
+    ApnsNotification notification = new ApnsNotification(%222342%22, %22%7B%7D%22);%0A%0A    @Test%0A    public void pushEvantually() %7B%0A        ConnectionStub connection = spy(new ConnectionStub(0, 1));%0A        ApnsService service = newService(connection, null);%0A%0A        service.push(notification);%0A        connection.semaphor.acquireUninterruptibly();%0A%0A        verify(connection, times(1)).sendMessage(notification);%0A    %7D%0A%0A
     @Test%0A  
@@ -2387,16 +2387,24 @@
 ) %3C time
+ + delay
 ));%0A    

improve queue tests (avoid thread errors)