package seedu.taskboss.logic.parser;

import java.util.List;
import java.util.Locale;
import java.util.Optional;

import com.joestelmach.natty.DateGroup;

import seedu.taskboss.commons.exceptions.IllegalValueException;
import seedu.taskboss.model.task.DateTime;

/*
 * Parses date
 */
public class DateParser {

    private static final String START_DATE = "START DATE: ";
    private static final String END_DATE = "END DATE: ";
    private static final String ERROR_INVALID_DATE = "Failed to understand given date.";
    private static final String ERROR_MULTIPLE_DATES = "Please only enter a single date.";

    private com.joestelmach.natty.Parser nattyParser;

    public DateParser() {
        this.nattyParser = new com.joestelmach.natty.Parser();
    }

    public DateTime parseStartDate(String rawStartDate) throws IllegalValueException {

        String currentStartDate = rawStartDate;
        if (Locale.getDefault().equals(Locale.US)) {
            currentStartDate = rawStartDate.replaceAll("(\\d{1,2})-(\\d{1,2})-((?:\\d\\d){1,2})", "$2-$1-$3");
        }

        List<DateGroup> dateGroupList = this.nattyParser.parse(currentStartDate);
        int numDates = countDates(dateGroupList);

        if (numDates == 0) {
            throw new IllegalValueException(START_DATE + ERROR_INVALID_DATE);
        }

        if (numDates > 1) {
            throw new IllegalValueException(START_DATE + ERROR_MULTIPLE_DATES);
        }

        DateGroup dateGroup = dateGroupList.get(0);

        return new DateTime(dateGroup.getDates().get(0), dateGroup.isDateInferred(), dateGroup.isTimeInferred());

    }

    public DateTime parseEndDate(String rawEndDate) throws IllegalValueException {

        String currentEndDate = rawEndDate;
        if (Locale.getDefault().equals(Locale.US)) {
            currentEndDate = rawEndDate.replaceAll("(\\d{1,2})-(\\d{1,2})-((?:\\d\\d){1,2})", "$2-$1-$3");
        }

        List<DateGroup> dateGroupList = this.nattyParser.parse(currentEndDate);
        int numDates = countDates(dateGroupList);

        if (numDates == 0) {
            throw new IllegalValueException(END_DATE + ERROR_INVALID_DATE);
        }

        if (numDates > 1) {
            throw new IllegalValueException(END_DATE + ERROR_MULTIPLE_DATES);
        }

        DateGroup dateGroup = dateGroupList.get(0);

        return new DateTime(dateGroup.getDates().get(0), dateGroup.isDateInferred(), dateGroup.isTimeInferred());

    }

    public Optional<String> convert(Optional<DateTime> dateTime) {
        return dateTime.isPresent() ? Optional.of(dateTime.toString()) : Optional.empty();
    }

    private int countDates(List<DateGroup> dateGroups) {
        int numTotalDates = 0;
        for (DateGroup dateGroup : dateGroups) {
            numTotalDates += dateGroup.getDates().size();
        }
        return numTotalDates;
    }

    public static String getStartDateInvalidDateError() {
        return START_DATE + ERROR_INVALID_DATE;
    }

    public static String getStartDateMultipleDatesError() {
        return START_DATE + ERROR_MULTIPLE_DATES;
    }

    public static String getEndDateInvalidDateError() {
        return END_DATE + ERROR_INVALID_DATE;
    }

    public static String getEndDateMultipleDatesError() {
        return END_DATE + ERROR_MULTIPLE_DATES;
    }
}

@@ -602,16 +602,171 @@
  date.%22;
+%0A    private static final String REGEX_US_DATE = %22(%5C%5Cd%7B1,2%7D)-(%5C%5Cd%7B1,2%7D)-((?:%5C%5Cd%5C%5Cd)%7B1,2%7D)%22;%0A    private static final String REGEX_NON_US_DATE = %22$2-$1-$3%22;
 %0A%0A    pr
@@ -919,90 +919,51 @@
    p
-ublic DateTime parseStartDate(String rawStartDate) throws IllegalValueException %7B%0A
+rivate List%3CDateGroup%3E parse(String date) %7B
 %0A   
@@ -981,37 +981,24 @@
  current
-Start
 Date = 
-rawStartD
+d
 ate;%0A   
@@ -1070,29 +1070,16 @@
 rent
-Start
 Date = 
-rawStartD
+d
 ate.
@@ -1093,61 +1093,40 @@
 All(
-%22(%5C%5Cd%7B1,2%7D)-(%5C%5Cd%7B1,2%7D)-((?:%5C%5Cd%5C%5Cd)%7B1,2%7D)%22, %22$2-$1-$3%22
+REGEX_US_DATE, REGEX_NON_US_DATE
 );%0A 
@@ -1205,16 +1205,197 @@
 (current
+Date);%0A        return dateGroupList;%0A    %7D%0A%0A    public DateTime parseStartDate(String rawStartDate) throws IllegalValueException %7B%0A%0A        List%3CDateGroup%3E dateGroupList = parse(raw
 StartDat
@@ -1949,223 +1949,8 @@
  %7B%0A%0A
-        String currentEndDate = rawEndDate;%0A        if (Locale.getDefault().equals(Locale.US)) %7B%0A            currentEndDate = rawEndDate.replaceAll(%22(%5C%5Cd%7B1,2%7D)-(%5C%5Cd%7B1,2%7D)-((?:%5C%5Cd%5C%5Cd)%7B1,2%7D)%22, %22$2-$1-$3%22);%0A        %7D%0A%0A
     
@@ -1989,38 +1989,17 @@
 t = 
-this.nattyParser.parse(current
+parse(raw
 EndD
@@ -2862,32 +2862,51 @@
 alDates;%0A    %7D%0A%0A
+    // for testing%0A
     public stati
@@ -2994,32 +2994,51 @@
 ID_DATE;%0A    %7D%0A%0A
+    // for testing%0A
     public stati
@@ -3130,32 +3130,51 @@
 E_DATES;%0A    %7D%0A%0A
+    // for testing%0A
     public stati
@@ -3258,32 +3258,51 @@
 ID_DATE;%0A    %7D%0A%0A
+    // for testing%0A
     public stati

Refactor parse method in DateParser