/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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.intellij.util.text;

import com.intellij.CommonBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Clock;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.intellij.util.EnvironmentUtil;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.win32.StdCallLibrary;
import org.jetbrains.annotations.NotNull;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DateFormatUtil {
  private static final Logger LOG = Logger.getInstance("com.intellij.util.text.DateFormatUtil");

  public static final long SECOND = 1000;
  public static final long MINUTE = SECOND * 60;
  public static final long HOUR = MINUTE * 60;
  public static final long DAY = HOUR * 24;
  public static final long WEEK = DAY * 7;
  public static final long MONTH = DAY * 30;
  public static final long YEAR = DAY * 365;
  public static final long DAY_FACTOR = 24L * 60 * 60 * 1000;

  // do not expose this constants - they are very likely to be changed in future
  private static final SyncDateFormat DATE_FORMAT;
  private static final SyncDateFormat TIME_FORMAT;
  private static final SyncDateFormat TIME_WITH_SECONDS_FORMAT;
  private static final SyncDateFormat DATE_TIME_FORMAT;
  private static final SyncDateFormat ABOUT_DATE_FORMAT;
  static {
    SyncDateFormat[] formats = getDateTimeFormats();
    DATE_FORMAT = formats[0];
    TIME_FORMAT = formats[1];
    TIME_WITH_SECONDS_FORMAT = formats[2];
    DATE_TIME_FORMAT = formats[3];
    ABOUT_DATE_FORMAT = new SyncDateFormat(DateFormat.getDateInstance(DateFormat.LONG, Locale.US));
  }

  private static final long[] DENOMINATORS = {YEAR, MONTH, WEEK, DAY, HOUR, MINUTE};
  private enum Period {YEAR, MONTH, WEEK, DAY, HOUR, MINUTE}
  private static final Period[] PERIODS = {Period.YEAR, Period.MONTH, Period.WEEK, Period.DAY, Period.HOUR, Period.MINUTE};

  private DateFormatUtil() { }

  public static long getDifferenceInDays(final Date startDate, final Date endDate) {
    return (endDate.getTime() - startDate.getTime() + DAY_FACTOR - 1000) / DAY_FACTOR;
  }

  @NotNull
  public static SyncDateFormat getDateFormat() {
    return DATE_FORMAT;
  }

  @NotNull
  public static SyncDateFormat getTimeFormat() {
    return TIME_FORMAT;
  }

  @NotNull
  public static SyncDateFormat getTimeWithSecondsFormat() {
    return TIME_WITH_SECONDS_FORMAT;
  }

  @NotNull
  public static SyncDateFormat getDateTimeFormat() {
    return DATE_TIME_FORMAT;
  }

  @NotNull
  public static String formatTime(@NotNull Date time) {
    return formatTime(time.getTime());
  }

  @NotNull
  public static String formatTime(long time) {
    return getTimeFormat().format(time);
  }

  @NotNull
  public static String formatTimeWithSeconds(@NotNull Date time) {
    return formatTimeWithSeconds(time.getTime());
  }

  @NotNull
  public static String formatTimeWithSeconds(long time) {
    return getTimeWithSecondsFormat().format(time);
  }

  @NotNull
  public static String formatDate(@NotNull Date time) {
    return formatDate(time.getTime());
  }

  @NotNull
  public static String formatDate(long time) {
    return getDateFormat().format(time);
  }

  @NotNull
  public static String formatPrettyDate(@NotNull Date date) {
    return formatPrettyDate(date.getTime());
  }

  @NotNull
  public static String formatPrettyDate(long time) {
    return doFormatPretty(time, false);
  }

  @NotNull
  public static String formatDateTime(Date date) {
    return formatDateTime(date.getTime());
  }

  @NotNull
  public static String formatDateTime(long time) {
    return getDateTimeFormat().format(time);
  }

  @NotNull
  public static String formatPrettyDateTime(Date date) {
    return formatPrettyDateTime(date.getTime());
  }

  @NotNull
  public static String formatPrettyDateTime(long time) {
    return doFormatPretty(time, true);
  }

  @NotNull
  private static String doFormatPretty(long time, boolean formatTime) {
    long currentTime = Clock.getTime();

    Calendar c = Calendar.getInstance();
    c.setTimeInMillis(currentTime);

    int currentYear = c.get(Calendar.YEAR);
    int currentDayOfYear = c.get(Calendar.DAY_OF_YEAR);

    c.setTimeInMillis(time);

    int year = c.get(Calendar.YEAR);
    int dayOfYear = c.get(Calendar.DAY_OF_YEAR);

    if (formatTime) {
      long delta = currentTime - time;
      if (delta <= HOUR && delta >= 0) {
        return CommonBundle.message("date.format.minutes.ago", (int)Math.rint(delta / (double)MINUTE));
      }
    }

    boolean isToday = currentYear == year && currentDayOfYear == dayOfYear;
    if (isToday) {
      String result = CommonBundle.message("date.format.today");
      if (formatTime) result += " " + TIME_FORMAT.format(time);
      return result;
    }

    boolean isYesterdayOnPreviousYear =
      (currentYear == year + 1) && currentDayOfYear == 1 && dayOfYear == c.getActualMaximum(Calendar.DAY_OF_YEAR);
    boolean isYesterday = isYesterdayOnPreviousYear || (currentYear == year && currentDayOfYear == dayOfYear + 1);

    if (isYesterday) {
      String result = CommonBundle.message("date.format.yesterday");
      if (formatTime) result += " " + TIME_FORMAT.format(time);
      return result;
    }

    return formatTime ? DATE_TIME_FORMAT.format(time) : DATE_FORMAT.format(time);
  }

  @NotNull
  public static String formatDuration(long delta) {
    StringBuilder buf = new StringBuilder();
    for (int i = 0; i < DENOMINATORS.length; i++) {
      long denominator = DENOMINATORS[i];
      int n = (int)(delta / denominator);
      if (n != 0) {
        buf.append(composeDurationMessage(PERIODS[i], n));
        buf.append(' ');
        delta = delta % denominator;
      }
    }

    if (buf.length() == 0) return CommonBundle.message("date.format.less.than.a.minute");
    return buf.toString().trim();
  }

  private static String composeDurationMessage(final Period period, final int n) {
    switch (period) {
      case DAY:
        return CommonBundle.message("date.format.n.days", n);
      case MINUTE:
        return CommonBundle.message("date.format.n.minutes", n);
      case HOUR:
        return CommonBundle.message("date.format.n.hours", n);
      case MONTH:
        return CommonBundle.message("date.format.n.months", n);
      case WEEK:
        return CommonBundle.message("date.format.n.weeks", n);
      default:
        return CommonBundle.message("date.format.n.years", n);
    }
  }

  @NotNull
  public static String formatFrequency(long time) {
    return CommonBundle.message("date.frequency", formatBetweenDates(time, 0));
  }

  @NotNull
  public static String formatBetweenDates(long d1, long d2) {
    long delta = Math.abs(d1 - d2);
    if (delta == 0) return CommonBundle.message("date.format.right.now");

    int n = -1;
    int i;
    for (i = 0; i < DENOMINATORS.length; i++) {
      long denominator = DENOMINATORS[i];
      if (delta >= denominator) {
        n = (int)(delta / denominator);
        break;
      }
    }

    if (d2 > d1) {
      if (n <= 0) {
        return CommonBundle.message("date.format.a.few.moments.ago");
      }
      else {
        return someTimeAgoMessage(PERIODS[i], n);
      }
    }
    else if (d2 < d1) {
      if (n <= 0) {
        return CommonBundle.message("date.format.in.a.few.moments");
      }
      else {
        return composeInSomeTimeMessage(PERIODS[i], n);
      }
    }

    return "";
  }

  @NotNull
  public static String formatAboutDialogDate(@NotNull Date date) {
    return ABOUT_DATE_FORMAT.format(date);
  }

  // helpers

  private static String someTimeAgoMessage(final Period period, final int n) {
    switch (period) {
      case DAY:
        return CommonBundle.message("date.format.n.days.ago", n);
      case MINUTE:
        return CommonBundle.message("date.format.n.minutes.ago", n);
      case HOUR:
        return CommonBundle.message("date.format.n.hours.ago", n);
      case MONTH:
        return CommonBundle.message("date.format.n.months.ago", n);
      case WEEK:
        return CommonBundle.message("date.format.n.weeks.ago", n);
      default:
        return CommonBundle.message("date.format.n.years.ago", n);
    }
  }

  private static String composeInSomeTimeMessage(final Period period, final int n) {
    switch (period) {
      case DAY:
        return CommonBundle.message("date.format.in.n.days", n);
      case MINUTE:
        return CommonBundle.message("date.format.in.n.minutes", n);
      case HOUR:
        return CommonBundle.message("date.format.in.n.hours", n);
      case MONTH:
        return CommonBundle.message("date.format.in.n.months", n);
      case WEEK:
        return CommonBundle.message("date.format.in.n.weeks", n);
      default:
        return CommonBundle.message("date.format.in.n.years", n);
    }
  }

  private static SyncDateFormat[] getDateTimeFormats() {
    DateFormat[] formats = new DateFormat[4];

    boolean loaded = false;
    try {
      if (SystemInfo.isWin7OrNewer) {
        loaded = getWindowsFormats(formats);
      }
      else if (SystemInfo.isMac) {
        loaded = getMacFormats(formats);
      }
      else if (SystemInfo.isUnix) {
        loaded = getUnixFormats(formats);
      }
    }
    catch (Throwable t) {
      LOG.error(t);
    }

    if (!loaded) {
      formats[0] = DateFormat.getDateInstance(DateFormat.SHORT);
      formats[1] = DateFormat.getTimeInstance(DateFormat.SHORT);
      formats[2] = DateFormat.getTimeInstance(DateFormat.MEDIUM);
      formats[3] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
    }

    SyncDateFormat[] synced = new SyncDateFormat[4];
    for (int i = 0; i < formats.length; i++) {
      synced[i] = new SyncDateFormat(formats[i]);
    }
    return synced;
  }

  private static boolean getMacFormats(DateFormat[] formats) {
    final int MacFormatterNoStyle = 0;
    final int MacFormatterShortStyle = 1;
    final int MacFormatterMediumStyle = 2;
    final int MacFormatterBehavior_10_4 = 1040;

    ID autoReleasePool = Foundation.invoke("NSAutoreleasePool", "new");
    try {
      ID dateFormatter = Foundation.invoke("NSDateFormatter", "new");
      Foundation.invoke(dateFormatter, Foundation.createSelector("setFormatterBehavior:"), MacFormatterBehavior_10_4);

      formats[0] = invokeFormatter(dateFormatter, MacFormatterNoStyle, MacFormatterShortStyle);  // short date
      formats[1] = invokeFormatter(dateFormatter, MacFormatterShortStyle, MacFormatterNoStyle);  // short time
      formats[2] = invokeFormatter(dateFormatter, MacFormatterMediumStyle, MacFormatterNoStyle);  // medium time
      formats[3] = invokeFormatter(dateFormatter, MacFormatterShortStyle, MacFormatterShortStyle);  // short date/time

      return true;
    }
    finally {
      Foundation.invoke(autoReleasePool, Foundation.createSelector("release"));
    }
  }

  private static DateFormat invokeFormatter(ID dateFormatter, int timeStyle, int dateStyle) {
    Foundation.invoke(dateFormatter, Foundation.createSelector("setTimeStyle:"), timeStyle);
    Foundation.invoke(dateFormatter, Foundation.createSelector("setDateStyle:"), dateStyle);
    String format = Foundation.toStringViaUTF8(Foundation.invoke(dateFormatter, Foundation.createSelector("dateFormat")));
    assert format != null;
    return new SimpleDateFormat(format.trim());
  }

  private static boolean getUnixFormats(DateFormat[] formats) {
    String localeStr = EnvironmentUtil.getValue("LC_TIME");
    if (localeStr == null) return false;

    localeStr = localeStr.trim();
    int p = localeStr.indexOf('.');
    if (p > 0) localeStr = localeStr.substring(0, p);
    p = localeStr.indexOf('@');
    if (p > 0) localeStr = localeStr.substring(0, p);

    Locale locale;
    p = localeStr.indexOf('_');
    if (p < 0) {
      locale = new Locale(localeStr);
    }
    else {
      locale = new Locale(localeStr.substring(0, p), localeStr.substring(p + 1));
    }

    formats[0] = DateFormat.getDateInstance(DateFormat.SHORT, locale);
    formats[1] = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
    formats[2] = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);
    formats[3] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);

    return true;
  }

  @SuppressWarnings("SpellCheckingInspection")
  private interface Kernel32 extends StdCallLibrary {
    String LOCALE_NAME_USER_DEFAULT = null;

    int LOCALE_SSHORTDATE  = 0x0000001F;
    int LOCALE_SSHORTTIME  = 0x00000079;
    int LOCALE_STIMEFORMAT = 0x00001003;

    int GetLocaleInfoEx(String localeName, int lcType, Pointer lcData, int dataSize);
    int GetLastError();
  }

  private static boolean getWindowsFormats(DateFormat[] formats) {
    Kernel32 kernel32 = (Kernel32)Native.loadLibrary("Kernel32", Kernel32.class);
    int dataSize = 128, rv;
    Memory data = new Memory(dataSize);

    rv = kernel32.GetLocaleInfoEx(Kernel32.LOCALE_NAME_USER_DEFAULT, Kernel32.LOCALE_SSHORTDATE, data, dataSize);
    assert rv > 1 : kernel32.GetLastError();
    String shortDate = new String(data.getCharArray(0, rv - 1));

    rv = kernel32.GetLocaleInfoEx(Kernel32.LOCALE_NAME_USER_DEFAULT, Kernel32.LOCALE_SSHORTTIME, data, dataSize);
    assert rv > 1 : kernel32.GetLastError();
    String shortTime = StringUtil.replace(new String(data.getCharArray(0, rv - 1)), "tt", "a");

    rv = kernel32.GetLocaleInfoEx(Kernel32.LOCALE_NAME_USER_DEFAULT, Kernel32.LOCALE_STIMEFORMAT, data, dataSize);
    assert rv > 1 : kernel32.GetLastError();
    String mediumTime = StringUtil.replace(new String(data.getCharArray(0, rv - 1)), "tt", "a");

    formats[0] = new SimpleDateFormat(shortDate);
    formats[1] = new SimpleDateFormat(shortTime);
    formats[2] = new SimpleDateFormat(mediumTime);
    formats[3] = new SimpleDateFormat(shortDate + " " + shortTime);

    return true;
  }
}