// 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 "chrome/common/time_format.h"

#include <vector>

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/string16.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "unicode/datefmt.h"
#include "unicode/locid.h"
#include "unicode/plurfmt.h"
#include "unicode/plurrule.h"
#include "unicode/smpdtfmt.h"

using base::Time;
using base::TimeDelta;

namespace {

static const char kFallbackFormatSuffixShort[] = "}";
static const char kFallbackFormatSuffixLeft[] = " left}";
static const char kFallbackFormatSuffixAgo[] = " ago}";

// Contains message IDs for various time units and pluralities.
struct MessageIDs {
  // There are 4 different time units and 6 different pluralities.
  int ids[4][6];
};

// Message IDs for different time formats.
static const MessageIDs kTimeShortMessageIDs = { {
  {
    IDS_TIME_SECS_DEFAULT, IDS_TIME_SEC_SINGULAR, IDS_TIME_SECS_ZERO,
    IDS_TIME_SECS_TWO, IDS_TIME_SECS_FEW, IDS_TIME_SECS_MANY
  },
  {
    IDS_TIME_MINS_DEFAULT, IDS_TIME_MIN_SINGULAR, IDS_TIME_MINS_ZERO,
    IDS_TIME_MINS_TWO, IDS_TIME_MINS_FEW, IDS_TIME_MINS_MANY
  },
  {
    IDS_TIME_HOURS_DEFAULT, IDS_TIME_HOUR_SINGULAR, IDS_TIME_HOURS_ZERO,
    IDS_TIME_HOURS_TWO, IDS_TIME_HOURS_FEW, IDS_TIME_HOURS_MANY
  },
  {
    IDS_TIME_DAYS_DEFAULT, IDS_TIME_DAY_SINGULAR, IDS_TIME_DAYS_ZERO,
    IDS_TIME_DAYS_TWO, IDS_TIME_DAYS_FEW, IDS_TIME_DAYS_MANY
  }
} };

static const MessageIDs kTimeRemainingMessageIDs = { {
  {
    IDS_TIME_REMAINING_SECS_DEFAULT, IDS_TIME_REMAINING_SEC_SINGULAR,
    IDS_TIME_REMAINING_SECS_ZERO, IDS_TIME_REMAINING_SECS_TWO,
    IDS_TIME_REMAINING_SECS_FEW, IDS_TIME_REMAINING_SECS_MANY
  },
  {
    IDS_TIME_REMAINING_MINS_DEFAULT, IDS_TIME_REMAINING_MIN_SINGULAR,
    IDS_TIME_REMAINING_MINS_ZERO, IDS_TIME_REMAINING_MINS_TWO,
    IDS_TIME_REMAINING_MINS_FEW, IDS_TIME_REMAINING_MINS_MANY
  },
  {
    IDS_TIME_REMAINING_HOURS_DEFAULT, IDS_TIME_REMAINING_HOUR_SINGULAR,
    IDS_TIME_REMAINING_HOURS_ZERO, IDS_TIME_REMAINING_HOURS_TWO,
    IDS_TIME_REMAINING_HOURS_FEW, IDS_TIME_REMAINING_HOURS_MANY
  },
  {
    IDS_TIME_REMAINING_DAYS_DEFAULT, IDS_TIME_REMAINING_DAY_SINGULAR,
    IDS_TIME_REMAINING_DAYS_ZERO, IDS_TIME_REMAINING_DAYS_TWO,
    IDS_TIME_REMAINING_DAYS_FEW, IDS_TIME_REMAINING_DAYS_MANY
  }
} };

static const MessageIDs kTimeElapsedMessageIDs = { {
  {
    IDS_TIME_ELAPSED_SECS_DEFAULT, IDS_TIME_ELAPSED_SEC_SINGULAR,
    IDS_TIME_ELAPSED_SECS_ZERO, IDS_TIME_ELAPSED_SECS_TWO,
    IDS_TIME_ELAPSED_SECS_FEW, IDS_TIME_ELAPSED_SECS_MANY
  },
  {
    IDS_TIME_ELAPSED_MINS_DEFAULT, IDS_TIME_ELAPSED_MIN_SINGULAR,
    IDS_TIME_ELAPSED_MINS_ZERO, IDS_TIME_ELAPSED_MINS_TWO,
    IDS_TIME_ELAPSED_MINS_FEW, IDS_TIME_ELAPSED_MINS_MANY
  },
  {
    IDS_TIME_ELAPSED_HOURS_DEFAULT, IDS_TIME_ELAPSED_HOUR_SINGULAR,
    IDS_TIME_ELAPSED_HOURS_ZERO, IDS_TIME_ELAPSED_HOURS_TWO,
    IDS_TIME_ELAPSED_HOURS_FEW, IDS_TIME_ELAPSED_HOURS_MANY
  },
  {
    IDS_TIME_ELAPSED_DAYS_DEFAULT, IDS_TIME_ELAPSED_DAY_SINGULAR,
    IDS_TIME_ELAPSED_DAYS_ZERO, IDS_TIME_ELAPSED_DAYS_TWO,
    IDS_TIME_ELAPSED_DAYS_FEW, IDS_TIME_ELAPSED_DAYS_MANY
  }
} };

// Different format types.
enum FormatType {
  FORMAT_SHORT,
  FORMAT_REMAINING,
  FORMAT_ELAPSED,
};

}  // namespace

class TimeFormatter {
  public:
    const std::vector<icu::PluralFormat*>& formatter(FormatType format_type) {
      switch (format_type) {
        case FORMAT_SHORT:
          return short_formatter_;
        case FORMAT_REMAINING:
          return time_left_formatter_;
        case FORMAT_ELAPSED:
          return time_elapsed_formatter_;
        default:
          NOTREACHED();
          return short_formatter_;
      }
    }
  private:
    static const MessageIDs& GetMessageIDs(FormatType format_type) {
      switch (format_type) {
        case FORMAT_SHORT:
          return kTimeShortMessageIDs;
        case FORMAT_REMAINING:
          return kTimeRemainingMessageIDs;
        case FORMAT_ELAPSED:
          return kTimeElapsedMessageIDs;
        default:
          NOTREACHED();
          return kTimeShortMessageIDs;
      }
    }

    static const char* GetFallbackFormatSuffix(FormatType format_type) {
      switch (format_type) {
        case FORMAT_SHORT:
          return kFallbackFormatSuffixShort;
        case FORMAT_REMAINING:
          return kFallbackFormatSuffixLeft;
        case FORMAT_ELAPSED:
          return kFallbackFormatSuffixAgo;
        default:
          NOTREACHED();
          return kFallbackFormatSuffixShort;
      }
    }

    TimeFormatter() {
      BuildFormats(FORMAT_SHORT, &short_formatter_);
      BuildFormats(FORMAT_REMAINING, &time_left_formatter_);
      BuildFormats(FORMAT_ELAPSED, &time_elapsed_formatter_);
    }
    ~TimeFormatter() {
      STLDeleteContainerPointers(short_formatter_.begin(),
                                 short_formatter_.end());
      STLDeleteContainerPointers(time_left_formatter_.begin(),
                                 time_left_formatter_.end());
      STLDeleteContainerPointers(time_elapsed_formatter_.begin(),
                                 time_elapsed_formatter_.end());
    }
    friend struct base::DefaultLazyInstanceTraits<TimeFormatter>;

    std::vector<icu::PluralFormat*> short_formatter_;
    std::vector<icu::PluralFormat*> time_left_formatter_;
    std::vector<icu::PluralFormat*> time_elapsed_formatter_;
    static void BuildFormats(FormatType format_type,
                             std::vector<icu::PluralFormat*>* time_formats);
    static icu::PluralFormat* createFallbackFormat(
        const icu::PluralRules& rules, int index, FormatType format_type);

    DISALLOW_COPY_AND_ASSIGN(TimeFormatter);
};

static base::LazyInstance<TimeFormatter> g_time_formatter =
    LAZY_INSTANCE_INITIALIZER;

void TimeFormatter::BuildFormats(
    FormatType format_type, std::vector<icu::PluralFormat*>* time_formats) {
  const icu::UnicodeString kKeywords[] = {
    UNICODE_STRING_SIMPLE("other"), UNICODE_STRING_SIMPLE("one"),
    UNICODE_STRING_SIMPLE("zero"), UNICODE_STRING_SIMPLE("two"),
    UNICODE_STRING_SIMPLE("few"), UNICODE_STRING_SIMPLE("many")
  };
  UErrorCode err = U_ZERO_ERROR;
  scoped_ptr<icu::PluralRules> rules(
      icu::PluralRules::forLocale(icu::Locale::getDefault(), err));
  if (U_FAILURE(err)) {
    err = U_ZERO_ERROR;
    icu::UnicodeString fallback_rules("one: n is 1", -1, US_INV);
    rules.reset(icu::PluralRules::createRules(fallback_rules, err));
    DCHECK(U_SUCCESS(err));
  }

  const MessageIDs& message_ids = GetMessageIDs(format_type);

  for (int i = 0; i < 4; ++i) {
    icu::UnicodeString pattern;
    for (size_t j = 0; j < arraysize(kKeywords); ++j) {
      int msg_id = message_ids.ids[i][j];
      std::string sub_pattern = l10n_util::GetStringUTF8(msg_id);
      // NA means this keyword is not used in the current locale.
      // Even if a translator translated for this keyword, we do not
      // use it unless it's 'other' (j=0) or it's defined in the rules
      // for the current locale. Special-casing of 'other' will be removed
      // once ICU's isKeyword is fixed to return true for isKeyword('other').
      if (sub_pattern.compare("NA") != 0 &&
          (j == 0 || rules->isKeyword(kKeywords[j]))) {
          pattern += kKeywords[j];
          pattern += UNICODE_STRING_SIMPLE("{");
          pattern += icu::UnicodeString(sub_pattern.c_str(), "UTF-8");
          pattern += UNICODE_STRING_SIMPLE("}");
      }
    }
    icu::PluralFormat* format = new icu::PluralFormat(*rules, pattern, err);
    if (U_SUCCESS(err)) {
      time_formats->push_back(format);
    } else {
      delete format;
      time_formats->push_back(createFallbackFormat(*rules, i, format_type));
      // Reset it so that next ICU call can proceed.
      err = U_ZERO_ERROR;
    }
  }
}

// Create a hard-coded fallback plural format. This will never be called
// unless translators make a mistake.
icu::PluralFormat* TimeFormatter::createFallbackFormat(
    const icu::PluralRules& rules, int index, FormatType format_type) {
  const icu::UnicodeString kUnits[4][2] = {
    { UNICODE_STRING_SIMPLE("sec"), UNICODE_STRING_SIMPLE("secs") },
    { UNICODE_STRING_SIMPLE("min"), UNICODE_STRING_SIMPLE("mins") },
    { UNICODE_STRING_SIMPLE("hour"), UNICODE_STRING_SIMPLE("hours") },
    { UNICODE_STRING_SIMPLE("day"), UNICODE_STRING_SIMPLE("days") }
  };
  icu::UnicodeString suffix(GetFallbackFormatSuffix(format_type), -1, US_INV);
  icu::UnicodeString pattern;
  if (rules.isKeyword(UNICODE_STRING_SIMPLE("one"))) {
    pattern += UNICODE_STRING_SIMPLE("one{# ") + kUnits[index][0] + suffix;
  }
  pattern += UNICODE_STRING_SIMPLE(" other{# ") + kUnits[index][1] + suffix;
  UErrorCode err = U_ZERO_ERROR;
  icu::PluralFormat* format = new icu::PluralFormat(rules, pattern, err);
  DCHECK(U_SUCCESS(err));
  return format;
}

static string16 FormatTimeImpl(const TimeDelta& delta, FormatType format_type) {
  if (delta.ToInternalValue() < 0) {
    NOTREACHED() << "Negative duration";
    return string16();
  }

  int number;

  const std::vector<icu::PluralFormat*>& formatters =
    g_time_formatter.Get().formatter(format_type);

  UErrorCode error = U_ZERO_ERROR;
  icu::UnicodeString time_string;
  // Less than a minute gets "X seconds left"
  if (delta.ToInternalValue() < Time::kMicrosecondsPerMinute) {
    number = static_cast<int>(delta.ToInternalValue() /
                              Time::kMicrosecondsPerSecond);
    time_string = formatters[0]->format(number, error);

  // Less than 1 hour gets "X minutes left".
  } else if (delta.ToInternalValue() < Time::kMicrosecondsPerHour) {
    number = static_cast<int>(delta.ToInternalValue() /
                              Time::kMicrosecondsPerMinute);
    time_string = formatters[1]->format(number, error);

  // Less than 1 day remaining gets "X hours left"
  } else if (delta.ToInternalValue() < Time::kMicrosecondsPerDay) {
    number = static_cast<int>(delta.ToInternalValue() /
                              Time::kMicrosecondsPerHour);
    time_string = formatters[2]->format(number, error);

  // Anything bigger gets "X days left"
  } else {
    number = static_cast<int>(delta.ToInternalValue() /
                              Time::kMicrosecondsPerDay);
    time_string = formatters[3]->format(number, error);
  }

  // With the fallback added, this should never fail.
  DCHECK(U_SUCCESS(error));
  int capacity = time_string.length() + 1;
  DCHECK_GT(capacity, 1);
  string16 result;
  time_string.extract(static_cast<UChar*>(WriteInto(&result, capacity)),
                      capacity, error);
  DCHECK(U_SUCCESS(error));
  return result;
}

// static
string16 TimeFormat::TimeElapsed(const TimeDelta& delta) {
  return FormatTimeImpl(delta, FORMAT_ELAPSED);
}

// static
string16 TimeFormat::TimeRemaining(const TimeDelta& delta) {
  return FormatTimeImpl(delta, FORMAT_REMAINING);
}

// static
string16 TimeFormat::TimeRemainingShort(const TimeDelta& delta) {
  return FormatTimeImpl(delta, FORMAT_SHORT);
}

// static
string16 TimeFormat::RelativeDate(
    const Time& time,
    const Time* optional_midnight_today) {
  Time midnight_today = optional_midnight_today ? *optional_midnight_today :
      Time::Now().LocalMidnight();

  // Filter out "today" and "yesterday"
  if (time >= midnight_today)
    return l10n_util::GetStringUTF16(IDS_PAST_TIME_TODAY);
  else if (time >= midnight_today -
                   TimeDelta::FromMicroseconds(Time::kMicrosecondsPerDay))
    return l10n_util::GetStringUTF16(IDS_PAST_TIME_YESTERDAY);

  return string16();
}
