/*
 * Copyright 2011 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.utils;

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.ResourceBundle;
import java.util.TimeZone;

/**
 * Utility class of time functions.
 *
 * @author James Moger
 *
 */
public class TimeUtils {
	public static final long MIN = 1000 * 60L;

	public static final long HALFHOUR = MIN * 30L;

	public static final long ONEHOUR = HALFHOUR * 2;

	public static final long ONEDAY = ONEHOUR * 24L;

	public static final long ONEYEAR = ONEDAY * 365L;

	private final ResourceBundle translation;

	private final TimeZone timezone;

	public TimeUtils() {
		this(null, null);
	}

	public TimeUtils(ResourceBundle translation, TimeZone timezone) {
		this.translation = translation;
		this.timezone = timezone;
	}

	/**
	 * Returns true if date is today.
	 *
	 * @param date
	 * @return true if date is today
	 */
	public static boolean isToday(Date date, TimeZone timezone) {
		Date now = new Date();
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
		if (timezone != null) {
			df.setTimeZone(timezone);
		}
		return df.format(now).equals(df.format(date));
	}

	/**
	 * Returns true if date is yesterday.
	 *
	 * @param date
	 * @return true if date is yesterday
	 */
	public static boolean isYesterday(Date date, TimeZone timezone) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DATE, -1);
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
		if (timezone != null) {
			df.setTimeZone(timezone);
		}
		return df.format(cal.getTime()).equals(df.format(date));
	}

	/**
	 * Returns the string representation of the duration as days, months and/or
	 * years.
	 *
	 * @param days
	 * @return duration as string in days, months, and/or years
	 */
	public String duration(int days) {
		if (days <= 60) {
			return (days > 1 ? translate(days, "gb.duration.days", "{0} days") : translate("gb.duration.oneDay", "1 day"));
		} else if (days < 365) {
			int rem = days % 30;
			return translate(((days / 30) + (rem >= 15 ? 1 : 0)), "gb.duration.months", "{0} months");
		} else {
			int years = days / 365;
			int rem = days % 365;
			String yearsString = (years > 1 ? translate(years, "gb.duration.years", "{0} years") : translate("gb.duration.oneYear", "1 year"));
			if (rem < 30) {
				if (rem == 0) {
					return yearsString;
				} else {
					return yearsString + (rem >= 15 ? (", " + translate("gb.duration.oneMonth", "1 month")): "");
				}
			} else {
				int months = rem / 30;
				int remDays = rem % 30;
				if (remDays >= 15) {
					months++;
				}
				String monthsString = yearsString + ", "
						+ (months > 1 ? translate(months, "gb.duration.months", "{0} months") : translate("gb.duration.oneMonth", "1 month"));
				return monthsString;
			}
		}
	}

	/**
	 * Returns the number of minutes ago between the start time and the end
	 * time.
	 *
	 * @param date
	 * @param endTime
	 * @param roundup
	 * @return difference in minutes
	 */
	public static int minutesAgo(Date date, long endTime, boolean roundup) {
		long diff = endTime - date.getTime();
		int mins = (int) (diff / MIN);
		if (roundup && (diff % MIN) >= 30) {
			mins++;
		}
		return mins;
	}

	/**
	 * Return the difference in minutes between now and the date.
	 *
	 * @param date
	 * @param roundup
	 * @return minutes ago
	 */
	public static int minutesAgo(Date date, boolean roundup) {
		return minutesAgo(date, System.currentTimeMillis(), roundup);
	}

	/**
	 * Return the difference in hours between now and the date.
	 *
	 * @param date
	 * @param roundup
	 * @return hours ago
	 */
	public static int hoursAgo(Date date, boolean roundup) {
		long diff = System.currentTimeMillis() - date.getTime();
		int hours = (int) (diff / ONEHOUR);
		if (roundup && (diff % ONEHOUR) >= HALFHOUR) {
			hours++;
		}
		return hours;
	}

	/**
	 * Return the difference in days between now and the date.
	 *
	 * @param date
	 * @return days ago
	 */
	public static int daysAgo(Date date) {
		long today = ONEDAY * (System.currentTimeMillis()/ONEDAY);
		long day = ONEDAY * (date.getTime()/ONEDAY);
		long diff = today - day;
		int days = (int) (diff / ONEDAY);
		return days;
	}

	public String today() {
		return translate("gb.time.today", "today");
	}

	public String yesterday() {
		return translate("gb.time.yesterday", "yesterday");
	}

	/**
	 * Returns the string representation of the duration between now and the
	 * date.
	 *
	 * @param date
	 * @return duration as a string
	 */
	public String timeAgo(Date date) {
		return timeAgo(date, false);
	}

	/**
	 * Returns the CSS class for the date based on its age from Now.
	 *
	 * @param date
	 * @return the css class
	 */
	public String timeAgoCss(Date date) {
		return timeAgo(date, true);
	}

	/**
	 * Returns the string representation of the duration OR the css class for
	 * the duration.
	 *
	 * @param date
	 * @param css
	 * @return the string representation of the duration OR the css class
	 */
	private String timeAgo(Date date, boolean css) {
		if (isToday(date, timezone) || isYesterday(date, timezone)) {
			int mins = minutesAgo(date, true);
			if (mins >= 120) {
				if (css) {
					return "age1";
				}
				int hours = hoursAgo(date, true);
				if (hours > 23) {
					return yesterday();
				} else {
					return translate(hours, "gb.time.hoursAgo", "{0} hours ago");
				}
			}
			if (css) {
				return "age0";
			}
			if (mins > 2) {
				return translate(mins, "gb.time.minsAgo", "{0} mins ago");
			}
			return translate("gb.time.justNow", "just now");
		} else {
			int days = daysAgo(date);
			if (css) {
				if (days <= 7) {
					return "age2";
				} if (days <= 30) {
					return "age3";
				} else {
					return "age4";
				}
			}
			if (days < 365) {
				if (days <= 30) {
					return translate(days, "gb.time.daysAgo", "{0} days ago");
				} else if (days <= 90) {
					int weeks = days / 7;
					if (weeks == 12) {
						return translate(3, "gb.time.monthsAgo", "{0} months ago");
					} else {
						return translate(weeks, "gb.time.weeksAgo", "{0} weeks ago");
					}
				}
				int months = days / 30;
				int weeks = (days % 30) / 7;
				if (weeks >= 2) {
					months++;
				}
				return translate(months, "gb.time.monthsAgo", "{0} months ago");
			} else if (days == 365) {
				return translate("gb.time.oneYearAgo", "1 year ago");
			} else {
				int yr = days / 365;
				days = days % 365;
				int months = (yr * 12) + (days / 30);
				if (months > 23) {
					return translate(yr, "gb.time.yearsAgo", "{0} years ago");
				} else {
					return translate(months, "gb.time.monthsAgo", "{0} months ago");
				}
			}
		}
	}

	public String inFuture(Date date) {
		long diff = date.getTime() - System.currentTimeMillis();
		if (diff > ONEDAY) {
			double days = ((double) diff)/ONEDAY;
			return translate((int) Math.round(days), "gb.time.inDays", "in {0} days");
		} else {
			double hours = ((double) diff)/ONEHOUR;
			if (hours > 2) {
				return translate((int) Math.round(hours), "gb.time.inHours", "in {0} hours");
			} else {
				int mins = (int) (diff/MIN);
				return translate(mins, "gb.time.inMinutes", "in {0} minutes");
			}
		}
	}

	private String translate(String key, String defaultValue) {
		String value = defaultValue;
		if (translation != null && translation.containsKey(key)) {
			String aValue = translation.getString(key);
			if (!StringUtils.isEmpty(aValue)) {
				value = aValue;
			}
		}
		return value;
	}

	private String translate(int val, String key, String defaultPattern) {
		String pattern = defaultPattern;
		if (translation != null && translation.containsKey(key)) {
			String aValue = translation.getString(key);
			if (!StringUtils.isEmpty(aValue)) {
				pattern = aValue;
			}
		}
		return MessageFormat.format(pattern, val);
	}

	/**
	 * Convert a frequency string into minutes.
	 *
	 * @param frequency
	 * @param minimumMins
	 * @return minutes
	 */
	public static int convertFrequencyToMinutes(String frequency, int minimumMins) {
		// parse the frequency
		frequency = frequency.toLowerCase();
		int mins = minimumMins;
		if (!StringUtils.isEmpty(frequency)) {
			try {
				String str = frequency.trim();
				if (frequency.indexOf(' ') > -1) {
					str = str.substring(0, str.indexOf(' ')).trim();
				}
				mins = (int) Float.parseFloat(str);
			} catch (NumberFormatException e) {
			}
			if (mins < minimumMins) {
				mins = minimumMins;
			}
			if (frequency.indexOf("day") > -1) {
				// convert to minutes
				mins *= 1440;
			} else if (frequency.indexOf("hour") > -1) {
				// convert to minutes
				mins *= 60;
			}
		}
		return mins;
	}
}
