// Copyright 2017 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 "garnet/bin/timezone/timezone.h"

#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/syscalls.h>

#include <fstream>
#include <optional>
#include <utility>

#include "src/lib/fsl/vmo/file.h"
#include "src/lib/fsl/vmo/sized_vmo.h"
#include "src/lib/fxl/strings/string_number_conversions.h"
#include "third_party/icu/source/common/unicode/errorcode.h"
#include "third_party/icu/source/common/unicode/udata.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"

constexpr char kDefaultTimezone[] = "UTC";
constexpr int32_t kMillisecondsInMinute = 60000;

namespace time_zone {

TimezoneImpl::TimezoneImpl(std::unique_ptr<sys::ComponentContext> context,
                           const char icu_data_path[], const char tz_id_path[])
    : context_(std::move(context)),
      icu_data_path_(icu_data_path),
      tz_id_path_(tz_id_path),
      valid_(Init()),
      inspector_(context_.get()),
      timezone_property_(inspector_.root().CreateString("timezone", "")) {
  if (valid_) {
    inspector_.Health().Ok();
    LoadTimezone();
  }
  context_->outgoing()->AddPublicService(deprecated_bindings_.GetHandler(this));
}

TimezoneImpl::~TimezoneImpl() = default;

bool TimezoneImpl::Init() {
  fsl::SizedVmo icu_data;
  if (!fsl::VmoFromFilename(icu_data_path_, &icu_data)) {
    FX_LOGS(ERROR) << "Unable to load ICU data. Timezone data unavailable.";
    inspector_.Health().Unhealthy("Unable to load ICU data.");
    return false;
  }

  // Maps the ICU VMO into this process.
  uintptr_t icu_data_ptr = 0;
  if (zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ, 0, icu_data.vmo().get(), 0, icu_data.size(),
                  &icu_data_ptr) != ZX_OK) {
    FX_LOGS(ERROR) << "Unable to map ICU data into process.";
    inspector_.Health().Unhealthy("Unable to map ICU data into process.");
    return false;
  }

  // ICU-related initialization.
  UErrorCode icu_set_data_status = U_ZERO_ERROR;
  udata_setCommonData(reinterpret_cast<void*>(icu_data_ptr), &icu_set_data_status);
  if (icu_set_data_status != U_ZERO_ERROR) {
    FX_LOGS(ERROR) << "Unable to set common ICU data. "
                   << "Timezone data unavailable.";
    inspector_.Health().Unhealthy("Timezone data unavailable");
    return false;
  }

  return true;
}

void TimezoneImpl::GetTimezoneOffsetMinutes(int64_t milliseconds_since_epoch,
                                            GetTimezoneOffsetMinutesCallback callback) {
  if (!valid_) {
    callback(0, 0);
    return;
  }

  // If valid_ is true, then cached_state_ must be valid.
  FX_CHECK(cached_state_.has_value());
  auto& timezone = cached_state_->timezone;

  int32_t local_offset = 0, dst_offset = 0;
  UErrorCode error = U_ZERO_ERROR;
  // Local time is set to false, and local_offset/dst_offset/error are mutated
  // via non-const references.
  timezone->getOffset(static_cast<UDate>(milliseconds_since_epoch), false, local_offset, dst_offset,
                      error);
  if (error != U_ZERO_ERROR) {
    icu::ErrorCode icuError;
    icuError.set(error);
    FX_LOGS(ERROR) << "Unable to get correct offset: error code " << error << " "
                   << icuError.errorName();
    callback(0, 0);
    return;
  }
  local_offset /= kMillisecondsInMinute;
  dst_offset /= kMillisecondsInMinute;
  callback(local_offset, dst_offset);
}

void TimezoneImpl::NotifyWatchers(const std::string& new_timezone_id) {
  for (auto& watcher : deprecated_watchers_) {
    watcher->OnTimezoneOffsetChange(new_timezone_id);
  }
}

std::pair<bool, std::unique_ptr<icu::TimeZone>> TimezoneImpl::ValidateTimezoneId(
    const std::string& timezone_id) {
  std::unique_ptr<icu::TimeZone> timezone(icu::TimeZone::createTimeZone(timezone_id.c_str()));
  if ((*timezone) == icu::TimeZone::getUnknown()) {
    return {false, nullptr};
  }
  return {true, std::move(timezone)};
}

void TimezoneImpl::SetTimezone(std::string timezone_id, SetTimezoneCallback callback) {
  if (!valid_) {
    FX_LOGS(ERROR) << "Time service is not valid.";
    callback(false);
    return;
  }

  auto [is_valid, timezone] = ValidateTimezoneId(timezone_id);
  if (!is_valid) {
    FX_LOGS(ERROR) << "Timezone '" << timezone_id << "' is not valid.";
    callback(false);
    return;
  }

  timezone_property_.Set(timezone_id);
  cached_state_ = {timezone_id, std::move(timezone)};

  std::ofstream out_fstream(tz_id_path_, std::ofstream::trunc);
  if (!out_fstream.is_open()) {
    FX_LOGS(ERROR) << "Unable to open file for write '" << tz_id_path_ << "'";
    callback(false);
    return;
  }
  out_fstream << timezone_id;
  out_fstream.close();
  NotifyWatchers(timezone_id);
  callback(true);
}

void TimezoneImpl::GetTimezoneId(GetTimezoneIdCallback callback) {
  callback(cached_state_ ? cached_state_->timezone_id : kDefaultTimezone);
}

void TimezoneImpl::LoadTimezone() {
  std::string timezone_id;

  std::ifstream in_fstream(tz_id_path_);
  if (!in_fstream.is_open()) {
    timezone_id = kDefaultTimezone;
  } else {
    in_fstream >> timezone_id;
    in_fstream.close();
  }

  if (timezone_id.empty()) {
    FX_LOGS(ERROR) << "TZ file empty at '" << tz_id_path_ << "'";
    inspector_.Health().Unhealthy("TZ file is empty");
    timezone_id = kDefaultTimezone;
  }

  auto [is_valid, timezone] = ValidateTimezoneId(timezone_id);
  if (!is_valid) {
    FX_LOGS(ERROR) << "Saved TZ ID invalid: '" << timezone_id << "'";
    inspector_.Health().Unhealthy("Saved TZ id is invalid");
    timezone_id = kDefaultTimezone;
    timezone = ValidateTimezoneId(kDefaultTimezone).second;
  }

  timezone_property_.Set(timezone_id);
  cached_state_ = {timezone_id, std::move(timezone)};
}

void TimezoneImpl::ReleaseWatcher(fuchsia::deprecatedtimezone::TimezoneWatcher* watcher) {
  auto predicate = [watcher](const auto& target) { return target.get() == watcher; };
  deprecated_watchers_.erase(
      std::remove_if(deprecated_watchers_.begin(), deprecated_watchers_.end(), predicate));
}

void TimezoneImpl::Watch(
    fidl::InterfaceHandle<fuchsia::deprecatedtimezone::TimezoneWatcher> watcher) {
  fuchsia::deprecatedtimezone::TimezoneWatcherPtr watcher_proxy = watcher.Bind();
  fuchsia::deprecatedtimezone::TimezoneWatcher* proxy_raw_ptr = watcher_proxy.get();
  watcher_proxy.set_error_handler(
      [this, proxy_raw_ptr](zx_status_t status) { ReleaseWatcher(proxy_raw_ptr); });
  deprecated_watchers_.push_back(std::move(watcher_proxy));
}

}  // namespace time_zone
