// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/base/l10n/time_format.h"

#include <limits>

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "third_party/icu/source/common/unicode/unistr.h"
#include "ui/base/l10n/formatter.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_export.h"
#include "ui/strings/grit/ui_strings.h"

using base::Time;
using base::TimeDelta;
using ui::TimeFormat;

namespace ui {

UI_BASE_EXPORT base::LazyInstance<FormatterContainer> g_container =
    LAZY_INSTANCE_INITIALIZER;

// static
base::string16 TimeFormat::Simple(TimeFormat::Format format,
                                  TimeFormat::Length length,
                                  const base::TimeDelta& delta) {
  return Detailed(format, length, 0, delta);
}

// static
base::string16 TimeFormat::Detailed(TimeFormat::Format format,
                                    TimeFormat::Length length,
                                    int cutoff,
                                    const base::TimeDelta& delta) {
  if (delta < TimeDelta::FromSeconds(0)) {
    NOTREACHED() << "Negative duration";
    return base::string16();
  }

  // Negative cutoff: always use two-value format.
  if (cutoff < 0)
    cutoff = std::numeric_limits<int>::max();

  const TimeDelta one_minute(TimeDelta::FromMinutes(1));
  const TimeDelta one_hour(TimeDelta::FromHours(1));
  const TimeDelta one_day(TimeDelta::FromDays(1));
  const TimeDelta half_second(TimeDelta::FromMilliseconds(500));
  const TimeDelta half_minute(TimeDelta::FromSeconds(30));
  const TimeDelta half_hour(TimeDelta::FromMinutes(30));
  const TimeDelta half_day(TimeDelta::FromHours(12));

  // Rationale: Start by determining major (first) unit, then add minor (second)
  // unit if mandated by |cutoff|.
  icu::UnicodeString time_string;
  const Formatter* formatter = g_container.Get().Get(format, length);
  if (delta < one_minute - half_second) {
    // Anything up to 59.500 seconds is formatted as seconds.
    const int seconds = static_cast<int>((delta + half_second).InSeconds());
    formatter->Format(Formatter::UNIT_SEC, seconds, &time_string);

  } else if (delta < one_hour - (cutoff < 60 ? half_minute : half_second)) {
    // Anything up to 59.5 minutes (respectively 59:59.500 when |cutoff| permits
    // two-value output) is formatted as minutes (respectively minutes and
    // seconds).
    if (delta >= cutoff * one_minute - half_second) {
      const int minutes = (delta + half_minute).InMinutes();
      formatter->Format(Formatter::UNIT_MIN, minutes, &time_string);
    } else {
      const int minutes = (delta + half_second).InMinutes();
      const int seconds = static_cast<int>(
          (delta + half_second).InSeconds() % 60);
      formatter->Format(Formatter::TWO_UNITS_MIN_SEC,
                        minutes, seconds, &time_string);
    }

  } else if (delta < one_day - (cutoff < 24 ? half_hour : half_minute)) {
    // Anything up to 23.5 hours (respectively 23:59:30.000 when |cutoff|
    // permits two-value output) is formatted as hours (respectively hours and
    // minutes).
    if (delta >= cutoff * one_hour - half_minute) {
      const int hours = (delta + half_hour).InHours();
      formatter->Format(Formatter::UNIT_HOUR, hours, &time_string);
    } else {
      const int hours = (delta + half_minute).InHours();
      const int minutes = (delta + half_minute).InMinutes() % 60;
      formatter->Format(Formatter::TWO_UNITS_HOUR_MIN,
                        hours, minutes, &time_string);
    }

  } else {
    // Anything bigger is formatted as days (respectively days and hours).
    if (delta >= cutoff * one_day - half_hour) {
      const int days = (delta + half_day).InDays();
      formatter->Format(Formatter::UNIT_DAY, days, &time_string);
    } else {
      const int days = (delta + half_hour).InDays();
      const int hours = (delta + half_hour).InHours() % 24;
      formatter->Format(Formatter::TWO_UNITS_DAY_HOUR,
                        days, hours, &time_string);
    }
  }

  const int capacity = time_string.length() + 1;
  DCHECK_GT(capacity, 1);
  base::string16 result;
  UErrorCode error = U_ZERO_ERROR;
  time_string.extract(static_cast<UChar*>(base::WriteInto(&result, capacity)),
                      capacity, error);
  DCHECK(U_SUCCESS(error));
  return result;
}

// static
base::string16 TimeFormat::RelativeDate(
    const Time& time,
    const Time* optional_midnight_today) {
  Time midnight_today = optional_midnight_today ? *optional_midnight_today :
      Time::Now().LocalMidnight();
  TimeDelta day = TimeDelta::FromMicroseconds(Time::kMicrosecondsPerDay);
  Time tomorrow = midnight_today + day;
  Time yesterday = midnight_today - day;
  if (time >= tomorrow)
    return base::string16();
  else if (time >= midnight_today)
    return l10n_util::GetStringUTF16(IDS_PAST_TIME_TODAY);
  else if (time >= yesterday)
    return l10n_util::GetStringUTF16(IDS_PAST_TIME_YESTERDAY);
  return base::string16();
}

}  // namespace ui
