package net.ranides.assira.time2;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;

public abstract class HolidaySchedule {

    public abstract ZoneId getZone();

    public abstract Set<ZonedDate> getHolidays();

    @ZoneHazard
    public abstract boolean contains(ZonedDate date);

    public abstract boolean contains(ZonedDateTime datetime);

    public static class EmptyHolidaySchedule extends HolidaySchedule {

        @Override
        public ZoneId getZone() {
            return DateTimeUtils.ZONE_UTC;
        }

        @Override
        public Set<ZonedDate> getHolidays() {
            return Collections.emptySet();
        }

        @Override
        public boolean contains(ZonedDate date) {
            return false;
        }

        @Override
        public boolean contains(ZonedDateTime datetime) {
            return false;
        }
    }

    public static class SimpleHolidaySchedule extends HolidaySchedule {

        private final ZoneId zone;
        private final Set<ZonedDate> set;

        public SimpleHolidaySchedule(ZoneId zone, Collection<ZonedDate> set) {
            this.zone = zone;
            this.set = set.stream().map(date -> date.withZone(zone)).collect(Collectors.toSet());
        }

        @Override
        public ZoneId getZone() {
            return zone;
        }

        @Override
        public Set<ZonedDate> getHolidays() {
            return set;
        }

        @ZoneHazard
        @Override
        public boolean contains(ZonedDate date) {
            return set.contains(DateTimeUtils.withZone(date, getZone()));
        }

        @Override
        public boolean contains(ZonedDateTime datetime) {
            return set.contains(ZonedDate.of(DateTimeUtils.withZone(datetime, getZone())));
        }

    }

}
