package eu.dnetlib.miscutils.datetime;

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

/**
 * various date utilities.
 * 
 * @author michele
 * 
 */
public class DateUtils {

	private static final SimpleDateFormat ISO8601FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US);

	private transient final Date date;

	public DateUtils() {
		this.date = new Date();
	}

	public DateUtils(final Date date) {
		this.date = (Date) date.clone();
	}

	public String getDateAsISO8601String() {
		String result;
		synchronized (ISO8601FORMAT) {
			result = ISO8601FORMAT.format(this.date);
		}

		//convert YYYYMMDDTHH:mm:ss+HH00 into YYYYMMDDTHH:mm:ss+HH:00
		//- note the added colon for the Timezone
		return result.substring(0, result.length() - 2) + ":" + result.substring(result.length() - 2);
	}

	public Long getPrecisionTime() {
		return this.date.getTime();
	}

	public static long now() {
		return new Date().getTime();
	}

	public static String now_ISO8601() { // NOPMD
		String result;
		synchronized (ISO8601FORMAT) {
			result = ISO8601FORMAT.format(new Date());
		}
		//convert YYYYMMDDTHH:mm:ss+HH00 into YYYYMMDDTHH:mm:ss+HH:00
		//- note the added colon for the Timezone
		return result.substring(0, result.length() - 2) + ":" + result.substring(result.length() - 2);
	}

	/**
	 * parses a iso8601 date into a date.
	 * 
	 * @param date
	 *            string iso8601 date
	 * @return date object
	 */
	public Date parse(final String dateArg) {
		String date = dateArg;

		if ("".equals(date))
			return null;

		try {
			if (date.endsWith("Z")) {
				date = date.replace("Z", "+0000");
			} else if (date.length() < 20) {
				date += "+0000"; // NOPMD
			} else {
				final String end = date.substring(date.length() - 3);
				date = date.substring(0, date.length() - 3) + end.replace(":", "");
			}

			synchronized (ISO8601FORMAT) {
				return ISO8601FORMAT.parse(date);
			}
		} catch (ParseException e) {
			throw new IllegalStateException("invalid iso8601 date '" + dateArg + "' (even after normalizing it to '" + date + "')");
		}
	}

	public static String calculate_ISO8601(long l) {
		String result = ISO8601FORMAT.format(new Date(l));
		// convert YYYYMMDDTHH:mm:ss+HH00 into YYYYMMDDTHH:mm:ss+HH:00
		//- note the added colon for the Timezone
		result = result.substring(0, result.length() - 2) + ":" + result.substring(result.length() - 2);
		return result;
	}

	/**
	 * Extracts the duration part of a ISO8601 formatted date. Duration part is the part after the 'T'.
	 * 
	 * @param dateArg
	 * @return
	 */
	public String getDuration(final String dateArg) {
		String[] splitted = dateArg.split("T");
		if (splitted.length == 1)
			return "0";
		else
			return splitted[1];
	}
}
