//@@author A0138474X
package seedu.address.logic.parser;

import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_DATE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_DESCRIPTION;
import static seedu.address.logic.parser.CliSyntax.PREFIX_FAVOURITE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_FREQUENCY;
import static seedu.address.logic.parser.CliSyntax.PREFIX_PRIORITY;
import static seedu.address.logic.parser.CliSyntax.PREFIX_START;
import static seedu.address.logic.parser.CliSyntax.PREFIX_STARTTIME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TIME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_VENUE;

import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;

import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.logic.commands.AddCommand;
import seedu.address.logic.commands.Command;
import seedu.address.logic.commands.IncorrectCommand;
import seedu.address.logic.parser.ArgumentTokenizer.Prefix;

/**
 * Parses input arguments and creates a new AddCommand object
 */
public class AddCommandParser {

    private static AddCommandParser theOne;

    private AddCommandParser() {
    }

    public static AddCommandParser getInstance() {
        if (theOne == null) {
            theOne = new AddCommandParser();
        }
        return theOne;
    }
    /**
     * Parses the given {@code String} of arguments in the context of the AddCommand
     * and returns an AddCommand object for execution.
     */
    public static Command parse(String args) {
        if (args == null) {
            return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
        }
        ArgumentTokenizer argsTokenizer =
                new ArgumentTokenizer(PREFIX_DATE, PREFIX_TIME, PREFIX_TAG, PREFIX_DESCRIPTION,
                        PREFIX_VENUE, PREFIX_PRIORITY, PREFIX_FAVOURITE, PREFIX_START,
                        PREFIX_STARTTIME, PREFIX_FREQUENCY);
        argsTokenizer.tokenize(args);
        try {
            String name = argsTokenizer.getPreamble().get();
            String date = null, startDate = null, time = null, startTime = null,
                    tag = null, description = null, venue = null, priority = null, frequency = null;
            List<String> list = Arrays.asList(date, startDate, time, startTime,
                    tag, description, venue, priority, frequency);
            List<Prefix> prefixList = Arrays.asList(PREFIX_DATE, PREFIX_START,
                    PREFIX_TIME, PREFIX_STARTTIME, PREFIX_TAG, PREFIX_DESCRIPTION,
                    PREFIX_VENUE, PREFIX_VENUE, PREFIX_FREQUENCY);
            list.forEach(element -> element =
                    checkString(argsTokenizer.getValue(prefixList.get(list.indexOf(element)))));
            stringFactory(argsTokenizer, prefixList, date, startDate,
                    time, startTime, tag, description, venue, priority, frequency);
            boolean isEvent = checkStart(startDate) || checkStart(startTime);
            boolean isFavourite = checkPresent(argsTokenizer.getValue(PREFIX_FAVOURITE));
            boolean isRecurring = !frequency.isEmpty();
            return new AddCommand(name, date, startDate, time, startTime, tag,
                    description, venue, priority, frequency, isFavourite, isEvent, isRecurring);
        } catch (NoSuchElementException ive) {
            return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
        } catch (IllegalValueException ive) {
            return new IncorrectCommand(ive.getMessage());
        }
    }

    private static boolean checkStart(String start) {
        return !start.isEmpty();
    }

    private static boolean checkPresent(Optional<String> args) {
        return args.isPresent();
    }

    private static String checkString(Optional<String> args) {
        return args.orElse("");
    }

    private static void stringFactory(ArgumentTokenizer argsTokenizer, List<Prefix> prefixList, String...strings) {
        List<String> stringList = Arrays.asList(strings);
        for (String string : strings) {
            string = checkString(argsTokenizer.getValue(prefixList.get(stringList.indexOf(string))));
        }
    }
}

@@ -805,56 +805,8 @@
 E;%0A%0A
-import java.util.Arrays;%0Aimport java.util.List;%0A
 impo
@@ -838,24 +838,24 @@
 tException;%0A
+
 import java.
@@ -1083,68 +1083,8 @@
 and;
-%0Aimport seedu.address.logic.parser.ArgumentTokenizer.Prefix;
 %0A%0A/*
@@ -2218,162 +2218,138 @@
 e = 
-null, startDate = null, time = null, startTime = null,%0A                    tag = null, description = null, venue = null, priority = null, frequency = null
+checkString(argsTokenizer.getValue(PREFIX_DATE));%0A            String startDate = checkString(argsTokenizer.getValue(PREFIX_START))
 ;%0A  
@@ -2362,511 +2362,396 @@
     
-List%3C
 String
-%3E list = Arrays.asList(date, startDate, time, startTime,%0A                    tag, description, venue, priority, frequency);%0A            List%3CPrefix%3E prefixList = Arrays.asList(PREFIX_DATE, PREFIX_START,%0A                    PREFIX_TIME, PREFIX_STARTTIME, PREFIX_TAG, PREFIX_DESCRIPTION,%0A                    PREFIX_VENUE, PREFIX_VENUE, PREFIX_FREQUENCY);%0A            list.forEach(element -%3E element =%0A                    checkString(argsTokenizer.getValue(prefixList.get(list.indexOf(element)))
+ time = checkString(argsTokenizer.getValue(PREFIX_TIME));%0A            String startTime = checkString(argsTokenizer.getValue(PREFIX_STARTTIME));%0A            String tag = checkString(argsTokenizer.getValue(PREFIX_TAG));%0A            String description = checkString(argsTokenizer.getValue(PREFIX_DESCRIPTION));%0A            String venue = checkString(argsTokenizer.getValue(PREFIX_VENUE
 ));%0A
@@ -2766,147 +2766,163 @@
     
-s
+S
 tring
-Factory(argsTokenizer, prefixList, date, startDate,%0A                    time, startTime, tag, description, venue, priority, frequency
+ priority = checkString(argsTokenizer.getValue(PREFIX_PRIORITY));%0A            String frequency = checkString(argsTokenizer.getValue(PREFIX_FREQUENCY)
 );%0A 
@@ -3908,338 +3908,6 @@
  %7D%0A%0A
-    private static void stringFactory(ArgumentTokenizer argsTokenizer, List%3CPrefix%3E prefixList, String...strings) %7B%0A        List%3CString%3E stringList = Arrays.asList(strings);%0A        for (String string : strings) %7B%0A            string = checkString(argsTokenizer.getValue(prefixList.get(stringList.indexOf(string))));%0A        %7D%0A    %7D%0A
 %7D%0A

Revert "[V0.5RC][Logic] try to apply SLAP onto addCommandParser"