package com.viettel.campaign.utils;

import org.apache.logging.log4j.util.Strings;
import org.joda.time.format.DateTimeFormat;

import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicReference;

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;

/**
 * @author anhvd_itsol
 */
public final class DateTimeUtil {
    public static final long DAY_IN_MILLIS = 86400000L;
    public static interface DateTimeProvider { long now(); }
    private static final AtomicReference<DateTimeProvider> PROVIDER = new AtomicReference<DateTimeProvider>();
    public static final DateTimeProvider getProvider() { return PROVIDER.get(); }
    static {
        PROVIDER.set(new DateTimeProvider() { @Override public long now() { return System.currentTimeMillis(); } });
    }

    public static Date currentTime() {
        return new Date(now());
    }

    public static Date currentDate() {
        return date(now());
    }

    public static final Date date(final long millis) {
        final int offset = getTimeZoneOffset(millis);
        long t = millis - ((t = (millis + offset) % DAY_IN_MILLIS) < 0 ? DAY_IN_MILLIS + t : t);
        t = t + (offset - getTimeZoneOffset(t)); return new Date(t);
    }

    public static int getTimeZoneOffset(long millis) {
        return TimeZone.getDefault().getOffset(millis);
    }

    public static long now() {
        return getProvider().now();
    }

    public static long toMillis(long nanos) {
        return MILLISECONDS.convert(nanos, NANOSECONDS);
    }

    public static long currentTimeMillis() {
        return getProvider().now();
    }

    /**
     * Format
     */
    public static String format(String pattern, long millis) {
        return DateTimeFormat.forPattern(pattern).print(millis);
    }

    public static String format(String pattern, Date date, String defaultValue) {
        if(date == null) return defaultValue;
        return format(pattern ,date.getTime());
    }

    /**
     *
     */
    public static boolean isValid(final long millis) {
        return millis > 0L;
    }
    /**
     *
     */
    public static long parse(final String pattern, String date) {
        return DateTimeFormat.forPattern(pattern).parseMillis(date);
    }

    public static Date parseDate(final String pattern, String date) {
        return Strings.isEmpty(date) ? null : date(parse(pattern, date));
    }

    /**
     *
     */
}
