package com.conveyal.gtfs.model;

import com.google.common.collect.Maps;
import java.time.LocalDate;

import java.io.Serializable;
import java.util.Map;

/**
 * This table does not exist in GTFS. It is a join of calendars and calendar_dates on service_id.
 * There should only be one Calendar per service_id. There should only be one calendar_date per tuple of
 * (service_id, date), which means there can be many calendar_dates per service_id.
 */
public class Service implements Serializable {

    public String   service_id;
    public Calendar calendar;
    public Map<LocalDate, CalendarDate> calendar_dates = Maps.newHashMap();

    public Service(String service_id) {
        this.service_id = service_id;
    }

    /**
     * Is this service active on the specified date?
     * @param date
     * @return
     */
    public boolean activeOn (LocalDate date) {
        // first check for exceptions
        CalendarDate exception = calendar_dates.get(date);

        if (exception != null)
            return exception.exception_type == 1;

        else if (calendar == null)
            return false;

        else {
            int gtfsDate = date.getYear() * 10000 + date.getMonthValue() * 100 + date.getDayOfMonth();
            return calendar.end_date >= gtfsDate && calendar.start_date <= gtfsDate;
        }
    }
}

@@ -65,16 +65,45 @@
 ct.Maps;
+%0A%0Aimport java.time.DayOfWeek;
 %0Aimport 
@@ -1265,22 +1265,45 @@
         
-return
+boolean withinValidityRange =
  calenda
@@ -1360,16 +1360,803 @@
 tfsDate;
+%0A%0A            if (!withinValidityRange) return false;%0A%0A            switch (date.getDayOfWeek()) %7B%0A                case MONDAY:%0A                    return calendar.monday == 1;%0A                case TUESDAY:%0A                    return calendar.tuesday == 1;%0A                case WEDNESDAY:%0A                    return calendar.wednesday == 1;%0A                case THURSDAY:%0A                    return calendar.thursday == 1;%0A                case FRIDAY:%0A                    return calendar.friday == 1;%0A                case SATURDAY:%0A                    return calendar.saturday == 1;%0A                case SUNDAY:%0A                    return calendar.sunday == 1;%0A                default:%0A                    throw new IllegalArgumentException(%22unknown day of week constant!%22);%0A            %7D
 %0A       

fix #11 (service.activeOn returning false positives). also fixes conveyal/r5#107.