package ru.yandex.wmtools.common.util;

import ru.yandex.common.util.collections.Pair;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author baton
 */
public class TimeFilter {
    private static final TimeFilter NULL_TIME_FILTER = new TimeFilter(null, null);

    private final Long from;
    private final Long to;

    private TimeFilter(Long from, Long to) {
        this.from = from;
        this.to = to;
    }

    public Long getFromInMilliseconds() {
        return from;
    }

    public Long getToInMilliseconds() {
        return to;
    }

    /**
     * NB: clients possibly should handle NumberFormatException!
     *
     * @param fromString time in milliseconds
     * @param toString   time in milliseconds
     * @return TimeFilter object
     * @throws NumberFormatException if given strings aren't longs
     */
    public static TimeFilter create(String fromString, String toString) throws NumberFormatException {
        Long from = (fromString != null) ? Long.parseLong(fromString) : null;
        Long to = (toString != null) ? Long.parseLong(toString) : null;

        return create(from, to);
    }

    public static TimeFilter create(Long from, Long to) {
        return new TimeFilter(from, to);
    }

    public static TimeFilter create(Date fromDate, Date toDate) {
        Long from = (fromDate != null) ? fromDate.getTime() : null;
        Long to = (toDate != null) ? toDate.getTime() : null;

        return create(from, to);
    }

    public static TimeFilter create(Pair<Date, Date> range) {
        return create(range.first, range.second);
    }

    public static TimeFilter create(String fromString, String toString, String formatPattern) throws ParseException {
        return create(fromString, toString, formatPattern, null);
    }

    /*
    * Adds 1 timeUnit (e.g. day) to the right boundary
     */
    public static TimeFilter create(String fromString, String toString, String formatPattern, Integer timeUnit) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat(formatPattern);

        Date from = (fromString != null) ? dateFormat.parse(fromString) : null;
        Date to = (toString != null) ? dateFormat.parse(toString) : null;
        if (timeUnit != null && to != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(to);
            cal.add(timeUnit, 1);
            to = cal.getTime();
        }

        return new TimeFilter((from != null) ? from.getTime() : null, (to != null) ? to.getTime() : null);
    }

    public static TimeFilter create(Integer lastDays) {
        if (lastDays == null) {
            return createNull();
        }

        Calendar from = Calendar.getInstance();
        SqlUtil.alignToMidnight(from);
        from.add(Calendar.DATE, -lastDays);

        return create(from.getTime(), null);
    }

    public static TimeFilter createNull() {
        return NULL_TIME_FILTER;
    }
}
