package org.realityforge.replicant.server.transport;

import org.realityforge.replicant.server.ChangeSet;
import org.testng.annotations.Test;
import static org.testng.Assert.*;

public class PacketQueueTest
{
  @Test
  public void basicFlow()
  {
    final PacketQueue queue = new PacketQueue();
    assertEquals( queue.getLastSequenceAcked(), 0 );
    assertEquals( queue.size(), 0 );

    final Packet p1 = queue.addPacket( null, null, new ChangeSet() );
    final Packet p2 = queue.addPacket( null, null, new ChangeSet() );
    final Packet p3 = queue.addPacket( null, null, new ChangeSet() );
    final Packet p4 = queue.addPacket( null, null, new ChangeSet() );

    assertEquals( queue.size(), 4 );

    assertEquals( queue.getPacket( 1 ), p1 );
    assertEquals( queue.getPacket( 2 ), p2 );
    assertEquals( queue.getPacket( 3 ), p3 );
    assertEquals( queue.getPacket( 4 ), p4 );

    assertEquals( queue.nextPacketToProcess().getSequence(), 1 );
    assertEquals( queue.nextPacketToProcess(), queue.getPacket( 1 ) );
    assertEquals( queue.nextPacketToProcess().getSequence(), 1 );

    queue.ack( 0 );
    assertEquals( queue.nextPacketToProcess().getSequence(), 1 );

    queue.ack( 1 );
    assertEquals( queue.size(), 3 );
    assertEquals( queue.nextPacketToProcess().getSequence(), 2 );
    assertEquals( queue.nextPacketToProcess(), queue.getPacket( 2 ) );

    assertEquals( queue.getPacket( 3 ).getSequence(), 3 );
    assertEquals( queue.getPacket( 4 ).getSequence(), 4 );
  }

  @Test
  public void ack()
  {
    final PacketQueue queue = new PacketQueue();
    assertEquals( queue.getLastSequenceAcked(), 0 );
    assertEquals( queue.size(), 0 );

    queue.addPacket( null, null, new ChangeSet() );
    queue.addPacket( null, null, new ChangeSet() );
    queue.addPacket( null, null, new ChangeSet() );
    queue.addPacket( null, null, new ChangeSet() );

    assertEquals( queue.size(), 4 );

    queue.ack( 0 );
    assertEquals( queue.getLastSequenceAcked(), 0 );
    queue.ack( 1 );
    assertEquals( queue.getLastSequenceAcked(), 1 );
    assertEquals( queue.size(), 3 );
    queue.ack( 0 );
    assertEquals( queue.getLastSequenceAcked(), 1 );
    assertEquals( queue.size(), 3 );
    queue.ack( 4 );
    assertEquals( queue.getLastSequenceAcked(), 4 );
    assertEquals( queue.size(), 0 );

    try
    {
      queue.ack( 5 );
      fail( "Attempted to ack future sequence" );
    }
    catch ( final IllegalStateException ise )
    {
      //Ignored
    }
  }
}

@@ -47,16 +47,49 @@
 sport;%0A%0A
+import javax.annotation.Nonnull;%0A
 import o
@@ -420,26 +420,8 @@
 %0A   
- final Packet p1 =
  que
@@ -426,36 +426,34 @@
 ueue.addPacket( 
-null
+21
 , null, new Chan
@@ -470,26 +470,8 @@
 %0A   
- final Packet p2 =
  que
@@ -476,36 +476,34 @@
 ueue.addPacket( 
-null
+22
 , null, new Chan
@@ -520,26 +520,8 @@
 %0A   
- final Packet p3 =
  que
@@ -526,36 +526,34 @@
 ueue.addPacket( 
-null
+23
 , null, new Chan
@@ -570,26 +570,8 @@
 %0A   
- final Packet p4 =
  que
@@ -576,36 +576,34 @@
 ueue.addPacket( 
-null
+24
 , null, new Chan
@@ -662,38 +662,32 @@
   assertEquals( 
-queue.
 getPacket( 1 ), 
@@ -683,63 +683,59 @@
 cket
-( 1 ), p1 );%0A    assertEquals( queue.getPacket( 2 ), p2
+BySequence( queue, 1 ).getRequestId(), (Integer) 21
  );%0A
@@ -744,38 +744,32 @@
   assertEquals( 
-queue.
 getPacket( 3 ), 
@@ -765,68 +765,63 @@
 cket
-( 3 ), p3 );%0A    assertEquals( queue.getPacket( 4 ), p4
+BySequence( queue, 2 ).getRequestId(), (Integer) 22
  );%0A
-%0A
     
@@ -838,52 +838,68 @@
 ls( 
-queue.nextPacketToProcess(
+getPacketBySequence( queue, 3 
 ).get
-S
+R
 eque
-nce(), 1
+stId(), (Integer) 23
  );%0A
@@ -920,61 +920,73 @@
 ls( 
-queue.nextPacketToProcess(), queue.getPacket( 1 )
+getPacketBySequence( queue, 4 ).getRequestId(), (Integer) 24
  );%0A
+%0A
     
@@ -1018,36 +1018,45 @@
 acketToProcess()
-.
+, 
 get
+PacketBy
 Sequence(), 1 );
@@ -1040,36 +1040,43 @@
 acketBySequence(
-)
+ queue
 , 1
+ )
  );%0A%0A    queue.a
@@ -1076,32 +1076,33 @@
 queue.ack( 0 );%0A
+%0A
     assertEquals
@@ -1122,36 +1122,45 @@
 acketToProcess()
-.
+, 
 get
+PacketBy
 Sequence(), 1 );
@@ -1152,20 +1152,27 @@
 equence(
-)
+ queue
 , 1
+ )
  );%0A%0A   
@@ -1270,20 +1270,29 @@
 rocess()
-.
+, 
 get
+PacketBy
 Sequence
@@ -1296,15 +1296,23 @@
 nce(
-)
+ queue
 , 2 )
-;
+ );%0A
 %0A   
@@ -1330,62 +1330,60 @@
 ls( 
-queue.nextPacketToProcess(), queue.getPacket( 2 )
+getPacketBySequence( queue, 3 ).getSequence(), 3
  );%0A
-%0A
     
@@ -1388,38 +1388,32 @@
   assertEquals( 
-queue.
 getPacket( 3 ).g
@@ -1409,11 +1409,28 @@
 cket
-( 3
+BySequence( queue, 4
  ).g
@@ -1447,70 +1447,238 @@
 (), 
-3
+4
  );%0A  
-  assertEquals( queue.getPacket( 4 ).getSequence(), 4 )
+%7D%0A%0A  @Nonnull%0A  private Packet getPacketBySequence( @Nonnull final PacketQueue queue, final int sequence )%0A  %7B%0A    final Packet packet = queue.findPacketBySequence( sequence );%0A    assertNotNull( packet );%0A    return packet
 ;%0A  

Simplify test to use requestId to track packets as that is how client code also does it