package net.openhft.chronicle.queue.impl.single;

import net.openhft.chronicle.queue.ChronicleQueue;
import net.openhft.chronicle.queue.ExcerptAppender;
import net.openhft.chronicle.queue.ExcerptTailer;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import static org.junit.Assert.assertEquals;

public final class MoveToIndexTest {
    @Rule
    public TemporaryFolder tmpFolder = new TemporaryFolder();

    @Test
    public void shouldMoveToPreviousIndexAfterDocumentIsConsumed() throws Exception {
        File queuePath = tmpFolder.newFolder("cq");

        try (ChronicleQueue queue = SingleChronicleQueueBuilder.binary(queuePath).build()) {
            ExcerptAppender appender = queue.acquireAppender();
            for (int i = 1; i < 10; ++i) {
                appender.writeText("id" + i);
            }

            ExcerptTailer tailer = queue.createTailer();
            assertNext(tailer, "id1");
            long index = tailer.index();
            assertNext(tailer, "id2");
            tailer.moveToIndex(index);
            assertNext(tailer, "id2");
            tailer.moveToIndex(index);
            assertNext(tailer, "id2");
        }
    }

    // https://github.com/OpenHFT/Chronicle-Queue/issues/401
    @Ignore
    @Test
    public void testRandomMove() throws Exception {
        int nbMessages = 10;
        int nbTests = 100;

        Map<Long, String> messages = new HashMap<>(nbMessages);

        File cqFolder = tmpFolder.newFolder("cq");
        try (ChronicleQueue queue = SingleChronicleQueueBuilder.binary(cqFolder).build()) {
            // create a queue and add some excerpts
            ExcerptAppender app = queue.acquireAppender();
            for (int i =0; i < nbMessages; i++) {
                final String message = "msg" + i;
                app.writeDocument(w -> w.write("message").object(message));
                if (i < nbMessages + 1) {
                    messages.put(app.lastIndexAppended(), message);
                }
            }

            Random random = new Random(1510298038000L);
            List<Long> offsets = new ArrayList<>(messages.keySet());
            ExcerptTailer tailer = queue.createTailer().toStart();
            String[] ret = new String[1];
            for (int i=0; i < nbTests; i++) {
                long offset = offsets.get(random.nextInt(messages.keySet().size()));
                tailer.moveToIndex(offset);
                tailer.readDocument(w -> ret[0] = (String) w.read("message").object());
                assertEquals(messages.get(offset), ret[0]);
                long index = tailer.index();
                tailer.readDocument(w -> ret[0] = (String) w.read("message").object());
            }
        }
    }

    private void assertNext(ExcerptTailer tailer, String expected) {
        String next = tailer.readText();
        assertEquals(expected, next);
    }
}

@@ -452,16 +452,68 @@
 .Random;
+%0Aimport java.util.concurrent.atomic.AtomicReference;
 %0A%0Aimport
@@ -1568,64 +1568,13 @@
     
+f
 in
-t nbMessages = 10;%0A        int nbTests = 100;%0A%0A       
+al
  Map
@@ -1595,17 +1595,23 @@
  message
-s
+ByIndex
  = new H
@@ -1623,72 +1623,11 @@
 p%3C%3E(
-nbMessages);%0A%0A        File cqFolder = tmpFolder.newFolder(%22cq%22
 );
+%0A
 %0A   
@@ -1691,23 +1691,53 @@
 der.
-binary(cq
+%0A                binary(tmpFolder.new
 Folder
+()
 ).bu
@@ -1801,32 +1801,38 @@
 pts%0A            
+final 
 ExcerptAppender 
@@ -1834,16 +1834,21 @@
 nder app
+ender
  = queue
@@ -1895,25 +1895,18 @@
  i =
+ 
 0; i %3C 
-nbMessages
+10
 ; i+
@@ -1979,16 +1979,21 @@
      app
+ender
 .writeDo
@@ -2061,70 +2061,30 @@
     
-if (i %3C nbMessages + 1) %7B%0A                    messages
+messageByIndex
 .put(app
 .las
@@ -2079,16 +2079,21 @@
 .put(app
+ender
 .lastInd
@@ -2120,26 +2120,8 @@
 e);%0A
-                %7D%0A
     
@@ -2143,16 +2143,22 @@
         
+final 
 Random r
@@ -2205,16 +2205,22 @@
         
+final 
 List%3CLon
@@ -2222,22 +2222,22 @@
 t%3CLong%3E 
-offset
+indice
 s = new 
@@ -2247,33 +2247,39 @@
 ayList%3C%3E(message
-s
+ByIndex
 .keySet());%0A    
@@ -2278,32 +2278,38 @@
 ));%0A            
+final 
 ExcerptTailer ta
@@ -2339,18 +2339,8 @@
 er()
-.toStart()
 ;%0A  
@@ -2353,36 +2353,79 @@
     
-String%5B%5D ret = new String%5B1%5D
+final AtomicReference%3CString%3E capturedMessage = new AtomicReference%3C%3E()
 ;%0A  
@@ -2448,23 +2448,21 @@
 nt i
-=
+ = 
 0; i %3C 
-nbTests
+100
 ; i+
@@ -2486,28 +2486,39 @@
     
-long offset = offset
+final long randomIndex = indice
 s.ge
@@ -2541,17 +2541,23 @@
 (message
-s
+ByIndex
 .keySet(
@@ -2603,22 +2603,27 @@
 ToIndex(
-offset
+randomIndex
 );%0A     
@@ -2654,33 +2654,44 @@
 cument(w -%3E 
-ret%5B0%5D = 
+capturedMessage.set(
 (String) w.r
@@ -2706,32 +2706,33 @@
 sage%22).object())
+)
 ;%0A              
@@ -2757,74 +2757,55 @@
 sage
-s.get(offset), ret%5B0%5D);%0A                long index = tailer.index(
+ByIndex.get(randomIndex), capturedMessage.get()
 );%0A 
@@ -2847,26 +2847,8 @@
 w -%3E
- ret%5B0%5D = (String)
  w.r

tidy test