package seedu.todo.guitests;

import static org.junit.Assert.*;

import java.time.LocalDateTime;

import org.junit.Before;
import org.junit.Test;

import seedu.todo.commons.util.DateUtil;
import seedu.todo.models.Task;
import seedu.todo.models.TodoListDB;

/**
 * @@author A0093907W
 */
public class UndoRedoCommandTest extends GuiTest {

    private final LocalDateTime oneDayFromNow = LocalDateTime.now().plusDays(1);
    private final String oneDayFromNowString = DateUtil.formatDate(oneDayFromNow);
    private final String oneDayFromNowIsoString = DateUtil.formatIsoDate(oneDayFromNow);
    private final LocalDateTime twoDaysFromNow = LocalDateTime.now().plusDays(2);
    private final String twoDaysFromNowString = DateUtil.formatDate(twoDaysFromNow);
    private final String twoDaysFromNowIsoString = DateUtil.formatIsoDate(twoDaysFromNow);
    
    String commandAdd1 = String.format("add task Buy KOI by \"%s 8pm\"", oneDayFromNowString);
    Task task1 = new Task();
    String commandAdd2 = String.format("add task Buy Milk by \"%s 9pm\"", twoDaysFromNowString);
    Task task2 = new Task();
    
    public UndoRedoCommandTest() {
        task1.setName("Buy KOI");
        task1.setCalendarDateTime(DateUtil.parseDateTime(String.format("%s 20:00:00", oneDayFromNowIsoString)));
        task2.setName("Buy Milk");
        task2.setDueDate(DateUtil.parseDateTime(String.format("%s 21:00:00", twoDaysFromNowIsoString)));
    }
    
    @Before
    public void resetDB() {
        console.runCommand("clear");
    }
    
    @Test
    public void undo_single() {
        assertTaskVisibleAfterCmd(commandAdd1, task1);
        assertTaskVisibleAfterCmd(commandAdd2, task2);
        assertTaskNotVisibleAfterCmd("undo", task2);
    }
    
    @Test
    public void undo_multiple() {
        assertTaskVisibleAfterCmd(commandAdd1, task1);
        assertTaskVisibleAfterCmd(commandAdd2, task2);
        assertTaskNotVisibleAfterCmd("undo 2", task1);
        assertTaskNotVisibleAfterCmd("list", task2); // A li'l hacky but oh well
    }
    
    @Test
    public void undo_notavailable() {
        assertTaskVisibleAfterCmd(commandAdd1, task1);
        assertTaskNotVisibleAfterCmd("undo", task1);
        console.runCommand("undo");
        console.runCommand("undo");
        assertEquals(console.getConsoleTextArea(), "There is no command to undo!");
    }
    
    @Test
    public void undo_multiple_notavailable() {
        console.runCommand("undo 2");
        assertEquals(console.getConsoleTextArea(), "We cannot undo 2 commands! At most, you can undo 1 command.");
    }
    
    @Test
    public void redo_single() {
        assertTaskVisibleAfterCmd(commandAdd1, task1);
        assertTaskNotVisibleAfterCmd("undo", task1);
        assertTaskVisibleAfterCmd("redo", task1);
    }
    
    @Test
    public void redo_multiple() {
        assertTaskVisibleAfterCmd(commandAdd1, task1);
        assertTaskVisibleAfterCmd(commandAdd2, task2);
        assertTaskNotVisibleAfterCmd("undo 2", task1);
        assertTaskNotVisibleAfterCmd("list", task2);
        assertTaskVisibleAfterCmd("redo 2", task1);
        assertTaskVisibleAfterCmd("list", task2);
    }
    
    @Test
    public void redo_notavailable() {
        console.runCommand("redo");
        assertEquals(console.getConsoleTextArea(), "There is no command to redo!");
    }
    
    @Test
    public void redo_multiple_notavailable() {
        console.runCommand("undo");
        console.runCommand("redo 2");
        assertEquals(console.getConsoleTextArea(), "We cannot redo 2 commands! At most, you can redo 1 command.");
    }
}

@@ -91,16 +91,40 @@
 eTime;%0A%0A
+import org.junit.After;%0A
 import o
@@ -1496,24 +1496,246 @@
 resetDB() %7B%0A
+        // Make sure there's something to clear, so that %60clear%60 will have an undo state.%0A        // Otherwise the testing environment may depend on the order of the running tests.%0A        console.runCommand(commandAdd1);%0A
         cons
@@ -2507,32 +2507,68 @@
 ommand(%22undo%22);%0A
+        console.runCommand(%22undo%22);%0A
         assertEq
@@ -2736,17 +2736,17 @@
 d(%22undo 
-2
+3
 %22);%0A    
@@ -2808,17 +2808,17 @@
 ot undo 
-2
+3
  command
@@ -2842,25 +2842,25 @@
 an undo 
-1
+2
  command
 .%22);%0A   
@@ -2843,32 +2843,33 @@
 n undo 2 command
+s
 .%22);%0A    %7D%0A    %0A

Fix undo/redo tests