// Copyright (C) 2013 The Android Open Source Project
//
// 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.google.gerrit.client;

import com.google.gerrit.client.changes.Util;

import java.util.Date;

/**
 * Formatter to format timestamps relative to the current time using time units
 * in the format defined by {@code git log --relative-date}.
 */
public class RelativeDateFormatter {
  static final long SECOND_IN_MILLIS = 1000;

  static final long MINUTE_IN_MILLIS = 60 * SECOND_IN_MILLIS;

  static final long HOUR_IN_MILLIS = 60 * MINUTE_IN_MILLIS;

  static final long DAY_IN_MILLIS = 24 * HOUR_IN_MILLIS;

  static final long WEEK_IN_MILLIS = 7 * DAY_IN_MILLIS;

  static final long MONTH_IN_MILLIS = 30 * DAY_IN_MILLIS;

  static final long YEAR_IN_MILLIS = 365 * DAY_IN_MILLIS;

  /**
   * @param when {@link Date} to format
   * @return age of given {@link Date} compared to now formatted in the same
   *         relative format as returned by {@code git log --relative-date}
   */
  @SuppressWarnings("boxing")
  public static String format(Date when) {
    long ageMillis = (new Date()).getTime() - when.getTime();

    // shouldn't happen in a perfect world
    if (ageMillis < 0) return Util.C.inTheFuture();

    // seconds
    if (ageMillis < upperLimit(MINUTE_IN_MILLIS)) {
      long seconds = round(ageMillis, SECOND_IN_MILLIS);
      if (seconds == 1) {
        return Util.C.oneSecondAgo();
      } else {
        return Util.M.secondsAgo(seconds);
      }
    }

    // minutes
    if (ageMillis < upperLimit(HOUR_IN_MILLIS)) {
      long minutes = round(ageMillis, MINUTE_IN_MILLIS);
      if (minutes == 1) {
        return Util.C.oneMinuteAgo();
      } else {
        return Util.M.minutesAgo(minutes);
      }
    }

    // hours
    if (ageMillis < upperLimit(DAY_IN_MILLIS)) {
      long hours = round(ageMillis, HOUR_IN_MILLIS);
      if (hours == 1) {
        return Util.C.oneHourAgo();
      } else {
        return Util.M.hoursAgo(hours);
      }
    }

    // up to 14 days use days
    if (ageMillis < 14 * DAY_IN_MILLIS) {
      long days = round(ageMillis, DAY_IN_MILLIS);
      if (days == 1) {
        return Util.C.oneDayAgo();
      } else {
        return Util.M.daysAgo(days);
      }
    }

    // up to 10 weeks use weeks
    if (ageMillis < 10 * WEEK_IN_MILLIS) {
      long weeks = round(ageMillis, WEEK_IN_MILLIS);
      if (weeks == 1) {
        return Util.C.oneWeekAgo();
      } else {
        return Util.M.weeksAgo(weeks);
      }
    }

    // months
    if (ageMillis < YEAR_IN_MILLIS) {
      long months = round(ageMillis, MONTH_IN_MILLIS);
      if (months == 1) {
        return Util.C.oneMonthAgo();
      } else {
        return Util.M.monthsAgo(months);
      }
    }

    // up to 5 years use "year, months" rounded to months
    if (ageMillis < 5 * YEAR_IN_MILLIS) {
      long years = ageMillis / YEAR_IN_MILLIS;
      String yearLabel = (years > 1) ? Util.C.years() : Util.C.year();
      long months = round(ageMillis % YEAR_IN_MILLIS, MONTH_IN_MILLIS);
      String monthLabel =
          (months > 1) ? Util.C.months() : (months == 1 ? Util.C.month() : "");
      if (months == 0) {
        return Util.M.years0MonthsAgo(years, yearLabel);
      } else {
        return Util.M.yearsMonthsAgo(years, yearLabel, months, monthLabel);
      }
    }

    // years
    long years = round(ageMillis, YEAR_IN_MILLIS);
    if (years == 1) {
      return Util.C.oneYearAgo();
    } else {
      return Util.M.yearsAgo(years);
    }
  }

  private static long upperLimit(long unit) {
    return unit + unit / 2;
  }

  private static long round(long n, long unit) {
    return (n + unit / 2) / unit;
  }
}
