package com.google.sps;

import com.google.sps.data.Event;
import com.google.sps.data.User;
import com.google.sps.data.VolunteeringOpportunity;
import com.google.sps.utilities.EventRanker;
import com.google.sps.utilities.TestUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests the ranking algorithm for event discovery */
@RunWith(JUnit4.class)
public final class EventRankingTest {
  private static final String CONSERVATION = "conservation";
  private static final String FOOD = "food";
  private static final String MUSIC = "music";
  private static final String SEWING = "sewing";
  private static final Set<String> INTERESTS_CONSERVATION_FOOD =
      new HashSet<>(Arrays.asList(CONSERVATION, FOOD));
  private static final Set<String> SKILLS_MUSIC =
      new HashSet<>(Arrays.asList(MUSIC));
  private static Event EVENT_CONSERVATION_FOOD_MUSIC;
  private static Event EVENT_FOOD_MUSIC;
  private static Event EVENT_CONSERVATION_MUSIC;
  private static Event EVENT_FOOD;
  private static Event EVENT_SEWING;
  private static User USER_CONSERVATION_FOOD_MUSIC;
  private static VolunteeringOpportunity OPPORTUNITY_MUSIC;

  @BeforeClass
  public static void setUp() throws Exception {
    EVENT_CONSERVATION_FOOD_MUSIC = TestUtils
        .newEvent()
        .toBuilder()
        .setLabels(new HashSet<>(Arrays.asList(CONSERVATION, FOOD, MUSIC)))
        .build();
    EVENT_FOOD_MUSIC = TestUtils
        .newEvent()
        .toBuilder()
        .setLabels(new HashSet<>(Arrays.asList(FOOD, MUSIC)))
        .build();
    EVENT_CONSERVATION_MUSIC = TestUtils
        .newEvent()
        .toBuilder()
        .setLabels(new HashSet<>(Arrays.asList(CONSERVATION, MUSIC)))
        .build();
    EVENT_FOOD = TestUtils
        .newEvent()
        .toBuilder()
        .setLabels(new HashSet<>(Arrays.asList(FOOD)))
        .build();
    EVENT_SEWING = TestUtils
        .newEvent()
        .toBuilder()
        .setLabels(new HashSet<>(Arrays.asList(SEWING)))
        .build();
    USER_CONSERVATION_FOOD_MUSIC = TestUtils
        .newUser()
        .toBuilder()
        .setInterests(INTERESTS_CONSERVATION_FOOD)
        .setSkills(SKILLS_MUSIC)
        .build();
    OPPORTUNITY_MUSIC = new VolunteeringOpportunity.Builder(EVENT_FOOD_MUSIC.getId(), "", 1).build();
    EVENT_FOOD_MUSIC = EVENT_FOOD_MUSIC.toBuilder().addOpportunity(OPPORTUNITY_MUSIC).build();
  }

  @Test
  public void testRankingEmptyEvents() throws IOException {
    Assert.assertEquals(
        new ArrayList<Event>(), EventRanker.rankEvents(USER_CONSERVATION_FOOD_MUSIC, new HashSet<Event>()));
  }

  @Test
  public void testRankingUntiedEvents() throws IOException {
    Set<Event> eventsToRank = new HashSet<>(
        Arrays.asList(EVENT_FOOD, EVENT_SEWING, EVENT_CONSERVATION_FOOD_MUSIC, EVENT_FOOD_MUSIC));
    List<Event> expectedEventRanking =
        Arrays.asList(EVENT_CONSERVATION_FOOD_MUSIC, EVENT_FOOD_MUSIC, EVENT_FOOD, EVENT_SEWING);

    List<Event> actualEventRanking = EventRanker.rankEvents(USER_CONSERVATION_FOOD_MUSIC, eventsToRank);

    Assert.assertEquals(expectedEventRanking, actualEventRanking);
  }

  @Test
  public void testRankingTiedEvents() throws IOException {
    Set<Event> eventsToRank = new HashSet<>(
        Arrays.asList(EVENT_CONSERVATION_MUSIC, EVENT_FOOD, EVENT_SEWING, EVENT_CONSERVATION_FOOD_MUSIC, EVENT_FOOD_MUSIC));
    List<Event> expectedEventRanking =
        Arrays.asList(EVENT_CONSERVATION_FOOD_MUSIC, EVENT_FOOD_MUSIC, EVENT_CONSERVATION_MUSIC, EVENT_FOOD, EVENT_SEWING);

    List<Event> actualEventRanking = EventRanker.rankEvents(USER_CONSERVATION_FOOD_MUSIC, eventsToRank);

    Assert.assertEquals(expectedEventRanking, actualEventRanking);
  }
}

@@ -18,16 +18,46 @@
 e.sps;%0A%0A
+import com.google.cloud.Date;%0A
 import c
@@ -1472,24 +1472,78 @@
 Exception %7B%0A
+    int currentYear = new java.util.Date().getYear();%0A
     EVENT_CO
@@ -1568,32 +1568,32 @@
 SIC = TestUtils%0A
-
         .newEven
@@ -1839,32 +1839,95 @@
 (FOOD, MUSIC)))%0A
+        .setDate(Date.fromYearMonthDay(currentYear + 1, 1, 1))%0A
         .build()
@@ -2072,32 +2072,95 @@
 ATION, MUSIC)))%0A
+        .setDate(Date.fromYearMonthDay(currentYear + 2, 1, 1))%0A
         .build()
@@ -2775,16 +2775,25 @@
 OD_MUSIC
+%0A        
 .toBuild
@@ -2796,16 +2796,25 @@
 uilder()
+%0A        
 .addOppo
@@ -2839,16 +2839,25 @@
 Y_MUSIC)
+%0A        
 .build()

Update test to have date testing