package guitests;

import org.junit.Test;

import seedu.task.commons.core.Messages;
import seedu.task.testutil.TestTask;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static seedu.task.logic.commands.RepeatCommand.MESSAGE_REPEAT_TASK_SUCCESS;

import java.util.concurrent.ThreadLocalRandom;

import static seedu.task.logic.commands.RepeatCommand.MESSAGE_INVALID_INTERVAL;

// @@author A0147944U
public class RepeatCommandTest extends TaskManagerGuiTest {

    @Test
    public void repeat() {

        TestTask[] currentList = td.getTypicalTasks();

        // repeat a random task in the list daily
        int targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "daily");

        // repeat a random task in the list weekly
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "weekly");

        // repeat a random task in the list fortnightly
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "fortnightly");

        // repeat a random task in the list monthly
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "monthly");

        // repeat a random task in the list yearly
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "yearly");

        // stop repeating the task that was just repeated
        assertRepeatSuccess(targetIndex, currentList, "stop");

        // repeat a random task in the list daily
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "d");

        // repeat a random task in the list weekly
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "w");

        // repeat a random task in the list fortnightly
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "f");

        // repeat a random task in the list monthly
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "m");

        // repeat a random task in the list yearly
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatSuccess(targetIndex, currentList, "y");

        // stop repeating the task that was just repeated
        assertRepeatSuccess(targetIndex, currentList, "end");

        // incorrect index
        assertRepeatWrongIndexFailure(50, "daily");

        // incorrect interval
        targetIndex = ThreadLocalRandom.current().nextInt(1, (currentList.length + 1));
        assertRepeatWrongIntervalFailure(targetIndex, "incorrect interval");
    }

    /**
     * Runs the repeat command to delete the task at specified index and
     * confirms the result is correct.
     * 
     * @param targetIndexOneIndexed
     *            e.g. to repeat the first task in the list, 1 should be given
     *            as the target index.
     * @param currentList
     *            A copy of the current list of tasks (before repeat command).
     */
    private void assertRepeatSuccess(int targetIndexOneIndexed, final TestTask[] currentList, String input) {
        // -1 because array uses zero indexing
        TestTask taskToRepeat = currentList[targetIndexOneIndexed - 1];
        String parsedInput = input;

        // confirm initial recurring parameter for task is different
        if ("stop".equals(parsedInput) || "end".equals(parsedInput)) {
            assertFalse(taskListPanel.getTask(targetIndexOneIndexed - 1).getRecurring().toString().equals("false"));
        } else {
            assertFalse(taskListPanel.getTask(targetIndexOneIndexed - 1).getRecurring().toString().equals(parsedInput));
        }

        commandBox.runCommand("repeat " + targetIndexOneIndexed + " " + parsedInput);

        // change value of input as command may store data as different value
        // for "stop" input
        if ("stop".equals(parsedInput) || "end".equals(parsedInput)) {
            parsedInput = "false";
        } else if ("d".equals(parsedInput)) {
            parsedInput = "daily";
        } else if ("w".equals(parsedInput)) {
            parsedInput = "weekly";
        } else if ("f".equals(parsedInput)) {
            parsedInput = "fortnightly";
        } else if ("m".equals(parsedInput)) {
            parsedInput = "monthly";
        } else if ("y".equals(parsedInput)) {
            parsedInput = "yearly";
        }

        // task
        assertTrue(taskListPanel.getTask(targetIndexOneIndexed - 1).getRecurring().toString().equals(parsedInput));

        // confirm the result message is correct
        assertResultMessage(String.format(MESSAGE_REPEAT_TASK_SUCCESS, taskToRepeat.getName().toString(), parsedInput));
    }

    private void assertRepeatWrongIndexFailure(int targetIndexOneIndexed, String input) {

        commandBox.runCommand("repeat " + targetIndexOneIndexed + " " + input);

        // confirm the result message is correct
        assertResultMessage(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX);
    }

    private void assertRepeatWrongIntervalFailure(int targetIndexOneIndexed, String input) {

        commandBox.runCommand("repeat " + targetIndexOneIndexed + " " + input);

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

}

@@ -29,20 +29,85 @@
 g.junit.
-Test
+Rule;%0Aimport org.junit.Test;%0Aimport org.junit.rules.ExpectedException
 ;%0A%0Aimpor
@@ -559,24 +559,99 @@
 rGuiTest %7B%0A%0A
+    @Rule%0A    public ExpectedException thrown = ExpectedException.none();%0A%0A
     @Test%0A  
@@ -670,16 +670,27 @@
 d repeat
+CommandTest
 () %7B%0A%0A  
@@ -3304,16 +3304,549 @@
 erval%22);
+%0A%0A    %7D%0A%0A    /**%0A     * Check if a recurring task will correctly repeat itself. If it does repeat%0A     * itself, getTask(1) will give IndexOutOfBoundsException.%0A     */%0A    @Test%0A    public void recurringTaskFunctionality() %7B%0A        commandBox.runCommand(%22clear%22);%0A        commandBox.runCommand(%22add task to repeat, at now%22);%0A        commandBox.runCommand(%22repeat 1 weekly%22);%0A        commandBox.runCommand(%22done 1%22);%0A        assertTrue(taskListPanel.getTask(0).getStartTime().compareTo(taskListPanel.getTask(1).getStartTime()) %3C 0);
 %0A    %7D%0A%0A

improve RepeatCommandTest