// Copyright 2019 The Fuchsia 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 "locale_util.h"

#include <lib/syslog/cpp/macros.h>

#include <ostream>
#include <unordered_set>

#include "third_party/icu/source/common/unicode/errorcode.h"
#include "third_party/icu/source/common/unicode/localebuilder.h"
#include "third_party/icu/source/common/unicode/locid.h"
#include "third_party/icu/source/common/unicode/unistr.h"
#include "third_party/icu/source/i18n/unicode/calendar.h"
#include "third_party/icu/source/i18n/unicode/dtptngen.h"
#include "third_party/icu/source/i18n/unicode/numsys.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "third_party/icu/source/i18n/unicode/ulocdata.h"

namespace intl {

using fuchsia::intl::CalendarId;
using fuchsia::intl::LocaleId;

namespace {

fit::result<std::string, zx_status_t> GetHourCycleValue(const icu::Locale& locale) {
  UErrorCode error_code = U_ZERO_ERROR;
  std::unique_ptr<icu::DateTimePatternGenerator> pattern_generator(
      icu::DateTimePatternGenerator::createInstance(locale, error_code));
  if (U_FAILURE(error_code)) {
    FX_LOGS(WARNING) << "Couldn't create DateTimePatternGenerator:" << u_errorName(error_code);
    return fit::error(ZX_ERR_INTERNAL);
  }
  auto pattern_unicode = pattern_generator->getBestPattern("j", error_code);
  std::string pattern;
  pattern_unicode.toUTF8String(pattern);
  if (pattern.find('h') != std::string::npos) {
    return fit::ok("h12");
  } else if (pattern.find('H') != std::string::npos) {
    return fit::ok("h23");
  } else if (pattern.find('k') != std::string::npos) {
    return fit::ok("h24");
  } else if (pattern.find('K') != std::string::npos) {
    return fit::ok("h11");
  } else {
    FX_LOGS(WARNING) << "Failed to get hour cycle for pattern: \"" << pattern << "\"";
    return fit::error(ZX_ERR_INTERNAL);
  }
}

fit::result<std::string, zx_status_t> GetMeasurementSystemValue(const icu::Locale& locale) {
  UErrorCode error_code = U_ZERO_ERROR;
  auto locale_id = locale.toLanguageTag<std::string>(error_code);
  UMeasurementSystem system = ulocdata_getMeasurementSystem(locale_id.c_str(), &error_code);
  if (U_FAILURE(error_code)) {
    FX_LOGS(WARNING) << "Failed to get measurement system: " << u_errorName(error_code);
    return fit::error(ZX_ERR_INTERNAL);
  }
  switch (system) {
    case UMS_SI:
      return fit::ok("metric");
    case UMS_UK:
      return fit::ok("uksystem");
    case UMS_US:
      return fit::ok("ussystem");
    default:
      return fit::error(ZX_ERR_INTERNAL);
  }
}

fit::result<std::string, zx_status_t> GetNumbersValue(const icu::Locale& locale) {
  UErrorCode error_code = U_ZERO_ERROR;
  std::unique_ptr<icu::NumberingSystem> numbering_system(
      icu::NumberingSystem::createInstance(locale, error_code));
  if (U_FAILURE(error_code)) {
    FX_LOGS(WARNING) << "Couldn't create NumberingSystem:" << u_errorName(error_code);
    return fit::error(ZX_ERR_INTERNAL);
  }
  return fit::ok(std::string(numbering_system->getName()));
}

}  // namespace

const std::string LocaleKeys::kCalendar = "ca";
const std::string LocaleKeys::kFirstDayOfWeek = "fw";
const std::string LocaleKeys::kHourCycle = "hc";
const std::string LocaleKeys::kMeasurementSystem = "ms";
const std::string LocaleKeys::kNumbers = "nu";
const std::string LocaleKeys::kTimeZone = "tz";

fit::result<icu::Locale, zx_status_t> LocaleIdToIcuLocale(
    const std::string& locale_id, const std::map<std::string, std::string>& unicode_extensions) {
  UErrorCode error_code = U_ZERO_ERROR;
  icu::LocaleBuilder locale_builder{};
  locale_builder.setLanguageTag(locale_id);
  for (const auto& [key, value] : unicode_extensions) {
    locale_builder.setUnicodeLocaleKeyword(key, value);
  }
  icu::Locale locale = locale_builder.build(error_code);
  if (U_FAILURE(error_code)) {
    return fit::error(ZX_ERR_INVALID_ARGS);
  }
  return fit::ok(std::move(locale));
}

fit::result<icu::Locale, zx_status_t> LocaleIdToIcuLocale(
    const LocaleId& locale_id, const std::map<std::string, std::string>& unicode_extensions) {
  return LocaleIdToIcuLocale(locale_id.id, unicode_extensions);
}

fit::result<std::string, zx_status_t> ExtractBcp47CalendarId(const CalendarId& calendar_id) {
  size_t start = calendar_id.id.find("-" + LocaleKeys::kCalendar + "-");
  if (start == std::string::npos) {
    return fit::error(ZX_ERR_INVALID_ARGS);
  }
  return fit::ok(calendar_id.id.substr(start + 4));
}

fit::result<LocaleId, zx_status_t> ExpandLocaleId(const icu::Locale& unexpanded_locale) {
  UErrorCode error_code = U_ZERO_ERROR;

  std::unordered_set<std::string> present_keys{};
  unexpanded_locale.getKeywords<std::string, std::insert_iterator<std::unordered_set<std::string>>>(
      std::inserter(present_keys, present_keys.end()), error_code);

  if (U_FAILURE(error_code)) {
    icu::ErrorCode error;
    error.set(error_code);
    FX_LOGS(WARNING) << "Couldn't read unexpanded locale: " << unexpanded_locale.getName()
                     << ", error: " << error.errorName();
  }

  icu::LocaleBuilder locale_builder{};
  locale_builder.setLocale(unexpanded_locale);

  if (present_keys.count(LocaleKeys::kCalendar) == 0 ||
      present_keys.count(LocaleKeys::kFirstDayOfWeek) == 0) {
    std::unique_ptr<icu::Calendar> calendar(
        icu::Calendar::createInstance(unexpanded_locale, error_code));
    if (U_FAILURE(error_code)) {
      icu::ErrorCode error;
      error.set(error_code);
      FX_LOGS(WARNING) << "Failed to load calendar data: " << unexpanded_locale.getName()
                       << ", error: " << error.errorName();
      return fit::error(ZX_ERR_INTERNAL);
    }

    if (present_keys.count(LocaleKeys::kCalendar) == 0) {
      auto calendar_value =
          uloc_toUnicodeLocaleType(LocaleKeys::kCalendar.c_str(), calendar->getType());
      if (calendar_value == nullptr) {
        FX_LOGS(WARNING) << "Bad calendar ID";
        return fit::error(ZX_ERR_INTERNAL);
      }
      locale_builder.setUnicodeLocaleKeyword(LocaleKeys::kCalendar, calendar_value);
    }

    if (present_keys.count(LocaleKeys::kFirstDayOfWeek) == 0) {
      UCalendarDaysOfWeek first_day = calendar->getFirstDayOfWeek(error_code);
      if (U_FAILURE(error_code)) {
        FX_LOGS(WARNING) << "Failed to get first day of week: " << u_errorName(error_code);
        return fit::error(ZX_ERR_INTERNAL);
      }
      std::string first_day_string = ToDayOfWeekString(first_day);
      locale_builder.setUnicodeLocaleKeyword(LocaleKeys::kFirstDayOfWeek, first_day_string);
    }
  }

  if (present_keys.count(LocaleKeys::kHourCycle) == 0) {
    auto hour_cycle_result = GetHourCycleValue(unexpanded_locale);
    if (hour_cycle_result.is_error()) {
      // Errors logged in GetHourCycleValue
      return fit::error(hour_cycle_result.error());
    }
    locale_builder.setUnicodeLocaleKeyword(LocaleKeys::kHourCycle.c_str(),
                                           hour_cycle_result.value());
  }

  if (present_keys.count(LocaleKeys::kMeasurementSystem) == 0) {
    auto measurement_system_result = GetMeasurementSystemValue(unexpanded_locale);
    if (measurement_system_result.is_error()) {
      // Errors logged in GetMeasurementSystemValue
      return fit::error(measurement_system_result.error());
    }
    locale_builder.setUnicodeLocaleKeyword(LocaleKeys::kMeasurementSystem.c_str(),
                                           measurement_system_result.value());
  }

  if (present_keys.count(LocaleKeys::kNumbers) == 0) {
    auto numbers_result = GetNumbersValue(unexpanded_locale);
    if (numbers_result.is_error()) {
      return fit::error(numbers_result.error());
    }
    locale_builder.setUnicodeLocaleKeyword(LocaleKeys::kNumbers.c_str(), numbers_result.value());
  }

  auto expanded_locale = locale_builder.build(error_code);
  if (U_FAILURE(error_code)) {
    FX_LOGS(WARNING) << "Failed to build expanded locale: " << u_errorName(error_code);
    return fit::error(ZX_ERR_INTERNAL);
  }

  auto id_str = expanded_locale.toLanguageTag<std::string>(error_code);
  if (U_FAILURE(error_code)) {
    FX_LOGS(WARNING) << "Failed to build language tag: " << u_errorName(error_code);
    return fit::error(ZX_ERR_INTERNAL);
  } else {
    return fit::ok(LocaleId{.id = id_str});
  }
}

std::string ToDayOfWeekString(UCalendarDaysOfWeek day_of_week) {
  switch (day_of_week) {
    case UCalendarDaysOfWeek::UCAL_SUNDAY:
      return "sun";
    case UCalendarDaysOfWeek::UCAL_MONDAY:
      return "mon";
    case UCalendarDaysOfWeek::UCAL_TUESDAY:
      return "tue";
    case UCalendarDaysOfWeek::UCAL_WEDNESDAY:
      return "wed";
    case UCalendarDaysOfWeek::UCAL_THURSDAY:
      return "thu";
    case UCalendarDaysOfWeek::UCAL_FRIDAY:
      return "fri";
    case UCalendarDaysOfWeek::UCAL_SATURDAY:
      return "sat";
  }
}

}  // namespace intl
