//@@author A0114395E
package guitests;

import static org.junit.Assert.assertTrue;
import static seedu.todoapp.logic.commands.DeleteCommand.MESSAGE_DELETE_TASK_SUCCESS;

import org.junit.Test;

import guitests.guihandles.TaskCardHandle;
import seedu.todoapp.logic.commands.UndoCommand;
import seedu.todoapp.testutil.TestTask;
import seedu.todoapp.testutil.TestUtil;

public class UndoCommandTest extends ToDoAppGuiTest {

    @Test
    public void undo() {
        // Test ADD
        TestTask[] currentList = td.getTypicalTasks();
        TestTask taskToAdd = td.hoon;
        assertAddSuccess(taskToAdd, currentList);
        currentList = TestUtil.addTasksToList(currentList, taskToAdd);

        assertUndoCommandSuccess(td.getTypicalTasks());

        // Test DELETE
        // Try delete first in list
        currentList = td.getTypicalTasks();
        int targetIndex = 1;
        assertDeleteSuccess(targetIndex, currentList);

        assertUndoCommandSuccess(td.getTypicalTasks());

        // Test CLEAR
        //verify a non-empty list can be cleared
        currentList = td.getTypicalTasks();
        assertClearCommandSuccess();

        assertUndoCommandSuccess(td.getTypicalTasks());
    }

    private void assertAddSuccess(TestTask taskToAdd, TestTask... currentList) {
        commandBox.runCommand(taskToAdd.getAddCommand());

        //confirm the new card contains the right data
        TaskCardHandle addedCard = taskListPanel.navigateToTask(taskToAdd.getName().fullName);
        assertMatching(taskToAdd, addedCard);

        //confirm the list now contains all previous tasks plus the new task
        TestTask[] expectedList = TestUtil.addTasksToList(currentList, taskToAdd);
        assertTrue(taskListPanel.isListMatching(expectedList));
    }

    /**
     * Runs the delete command to delete the task at specified index and confirms the result is correct.
     * @param targetIndexOneIndexed e.g. index 1 to delete the first task in the list,
     * @param currentList A copy of the current list of tasks (before deletion).
     */
    private void assertDeleteSuccess(int targetIndexOneIndexed, final TestTask[] currentList) {
        TestTask taskToDelete = currentList[targetIndexOneIndexed - 1]; // -1 as array uses zero indexing
        TestTask[] expectedRemainder = TestUtil.removeTaskFromList(currentList, targetIndexOneIndexed);

        commandBox.runCommand("delete " + targetIndexOneIndexed);

        //confirm the list now contains all previous tasks except the deleted task
        assertTrue(taskListPanel.isListMatching(expectedRemainder));

        //confirm the result message is correct
        assertResultMessage(String.format(MESSAGE_DELETE_TASK_SUCCESS, taskToDelete));
    }

    /*
     * Runs the clear command, and check that the list is empty
     */
    private void assertClearCommandSuccess() {
        commandBox.runCommand("clear");
        assertListSize(0);
        assertResultMessage("ToDoApp has been cleared!");
    }

    /*
     * Runs the undo command, and check that the list is back to the previous state
     */
    private void assertUndoCommandSuccess(TestTask[] expectedList) {
        commandBox.runCommand("undo");
        assertTrue(taskListPanel.isListMatching(expectedList));
        assertResultMessage(UndoCommand.MESSAGE_SUCCESS);
    }
}

@@ -445,16 +445,28 @@
 oid undo
+_add_success
 () %7B%0A   
@@ -745,32 +745,88 @@
 ypicalTasks());%0A
+    %7D%0A%0A    @Test%0A    public void undo_delete_success() %7B
 %0A        // Test
@@ -868,32 +868,43 @@
  in list%0A       
+ TestTask%5B%5D
  currentList = t
@@ -1061,24 +1061,805 @@
 alTasks());%0A
+    %7D%0A%0A    @Test%0A    public void undo_nothing_failure() %7B%0A        // Test UNDO-ing nothing%0A        TestTask%5B%5D currentList = td.getTypicalTasks();%0A%0A        commandBox.runCommand(%22undo%22);%0A        assertResultMessage(UndoCommand.MESSAGE_FAIL);%0A    %7D%0A%0A    @Test%0A    public void undo_moreThanComamnds_failure() %7B%0A        TestTask%5B%5D currentList = td.getTypicalTasks();%0A        TestTask taskToAdd = td.hoon;%0A        assertAddSuccess(taskToAdd, currentList);%0A        currentList = TestUtil.addTasksToList(currentList, taskToAdd);%0A%0A        assertUndoCommandSuccess(td.getTypicalTasks());%0A%0A        // Should have no more commands to undo%0A        commandBox.runCommand(%22undo%22);%0A        assertResultMessage(UndoCommand.MESSAGE_FAIL);%0A    %7D%0A%0A    @Test%0A    public void undo_clear_success() %7B    
 %0A        // 
@@ -1917,32 +1917,43 @@
  cleared%0A       
+ TestTask%5B%5D
  currentList = t

Split unit tests up, and added more tests for undo