package seedu.address.commons.util;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.TextStyle;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Locale;

import org.junit.Test;

import seedu.todo.commons.util.DateUtil;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

public class DateUtilTest {
	
	@Test
	public void toDate_equalTimestamps() {
		long currTimeMs = java.lang.System.currentTimeMillis();
		Date testDate = new Date(currTimeMs);
		LocalDateTime testDateTime = fromEpoch(currTimeMs);
		Date actualDate = DateUtil.toDate(testDateTime);
		
		assertEquals(testDate.getTime(), actualDate.getTime());
	}
	
	@Test
	public void toDate_differentTimestamps() {
		long currTimeMs = java.lang.System.currentTimeMillis();
		Date testDate = new Date(currTimeMs);
		LocalDateTime testDateTime = fromEpoch(currTimeMs + 1);
		Date actualDate = DateUtil.toDate(testDateTime);
		
		assertNotEquals(testDate.getTime(), actualDate.getTime());
	}
	
	@Test
	public void floorDate_sameDate() {
		long testEpoch1 = 1476099300000l; // 10/10/2016 @ 11:35am (UTC)
		long testEpoch2 = 1476099360000l; // 10/10/2016 @ 11:36am (UTC)
		LocalDateTime testDateTime1 = fromEpoch(testEpoch1);
		LocalDateTime testDateTime2 = fromEpoch(testEpoch2);
		
		assertEquals(DateUtil.floorDate(testDateTime1), DateUtil.floorDate(testDateTime2));
	}
	
	@Test
	public void floorDate_differentDate() {
		long testEpoch1 = 1476099300000l; // 10/10/2016 @ 11:35am (UTC)
		long testEpoch2 = 1476185700000l; // 11/10/2016 @ 11:35am (UTC)
		LocalDateTime testDateTime1 = fromEpoch(testEpoch1);
		LocalDateTime testDateTime2 = fromEpoch(testEpoch2);
		
		assertNotEquals(DateUtil.floorDate(testDateTime1), DateUtil.floorDate(testDateTime2));
	}
	
	@Test
	public void formatDayTests() {
	    LocalDateTime now = LocalDateTime.now();
	    assertEquals(DateUtil.formatDay(now), "Today " + now.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3) + " " + 
	            now.getDayOfMonth() + " " + now.getMonth().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3));
	    assertEquals(DateUtil.formatDay(now.plus(1, ChronoUnit.DAYS)), "Tomorrow " + 
	            now.plus(1, ChronoUnit.DAYS).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3) + 
	            " " + now.plus(1, ChronoUnit.DAYS).getDayOfMonth() + 
	            " " + now.plus(1, ChronoUnit.DAYS).getMonth().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3));
	    assertEquals(DateUtil.formatDay(now.plus(2, ChronoUnit.DAYS)), 
	            now.plus(2, ChronoUnit.DAYS).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US) + 
	            " " + now.plus(2, ChronoUnit.DAYS).getDayOfMonth() + 
	            " " + now.plus(2, ChronoUnit.DAYS).getMonth().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3));
	    assertEquals(DateUtil.formatDay(now.plus(6, ChronoUnit.DAYS)), 
	            now.plus(6, ChronoUnit.DAYS).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US) + 
	            " " + now.plus(6, ChronoUnit.DAYS).getDayOfMonth() + 
	            " " + now.plus(6, ChronoUnit.DAYS).getMonth().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3));
        assertEquals(DateUtil.formatDay(now.minus(1, ChronoUnit.DAYS)), "1 day ago");
        assertEquals(DateUtil.formatDay(now.minus(6, ChronoUnit.DAYS)), "6 days ago");
        assertEquals(DateUtil.formatDay(now.minus(14, ChronoUnit.DAYS)), "14 days ago");
	}
	
	private static LocalDateTime fromEpoch(long epoch) {
		return LocalDateTime.ofInstant(Instant.ofEpochMilli(epoch), ZoneId.systemDefault());
	}
	
}

@@ -1972,212 +1972,9 @@
 oday
- %22 + now.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3) + %22 %22 + %0A%09            now.getDayOfMonth() + %22 %22 + now.getMonth().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3)
+%22
 );%0A%09
@@ -2053,507 +2053,143 @@
 rrow
- %22 + %0A%09  
+%22);%0A%09
     
+%0A%09
     
-  now.plus(1, ChronoUnit.DAYS).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3) + %0A%09            %22 %22 + now.plus(1, ChronoUnit.DAYS).getDayOfMonth() + %0A%09            %22 %22 + now.plus(1, ChronoUnit.DAYS).getMonth().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3));%0A%09    assertEquals(DateUtil.formatDay(now.plus(2, ChronoUnit.DAYS)), %0A%09            now.plus(2, ChronoUnit.DAYS).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US) + %0A%09            %22 %22 +
+// Show day of week for d = %7Bn+2,...,n+6%7D where n = today%0A%09    for (int i = 2; i %3C= 6; i++) %7B%0A%09        String expected =
  now
@@ -2186,33 +2186,33 @@
 cted = now.plus(
-2
+i
 , ChronoUnit.DAY
@@ -2226,75 +2226,12 @@
 ayOf
-Month() + %0A%09            %22 %22 + now.plus(2, ChronoUnit.DAYS).getMonth
+Week
 ().g
@@ -2274,28 +2274,15 @@
 .US)
-.substring(0, 3));%0A%09
+;%0A%09    
     
@@ -2314,33 +2314,33 @@
 matDay(now.plus(
-6
+i
 , ChronoUnit.DAY
@@ -2348,301 +2348,33 @@
 )), 
-%0A%09            now.plus(6, ChronoUnit.DAYS).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US) + %0A%09            %22 %22 + now.plus(6, ChronoUnit.DAYS).getDayOfMonth() + %0A%09            %22 %22 + now.plus(6, ChronoUnit.DAYS).getMonth().getDisplayName(TextStyle.FULL, Locale.US).substring(0, 3));%0A    
+expected);%0A%09    %7D%0A%09    %0A%09
     

Update DateUtilTest for formatDay