// 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/network_time/timezone.h"

#include <fcntl.h>
#include <inttypes.h>
#include <sys/time.h>
#include <unistd.h>
#include <string>

#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include "fuchsia/hardware/rtc/cpp/fidl.h"
#include "garnet/bin/network_time/roughtime_server.h"
#include "garnet/bin/network_time/time_server_config.h"
#include "garnet/bin/network_time/time_util.h"
#include "lib/syslog/cpp/logger.h"
#include "zircon/system/ulib/zx/include/lib/zx/channel.h"

namespace time_server {

namespace rtc = fuchsia::hardware::rtc;

bool Timezone::Run() {
  FX_LOGS(INFO) << "started";
  return UpdateSystemTime(kDefaultUpdateAttempts);
}

bool Timezone::UpdateSystemTime(uint32_t tries) {
  TimeServerConfig config;
  if (!config.Parse(server_config_file_)) {
    FX_LOGS(ERROR) << "Failed to parse config file";
    return false;
  }

  const RoughTimeServer* server = nullptr;
  std::vector<RoughTimeServer> servers = config.ServerList();
  for (const auto& s : servers) {
    if (!s.IsValid()) {
      continue;
    }
    server = &s;
    break;
  }

  if (server == nullptr) {
    FX_LOGS(ERROR) << "No valid server";
    return false;
  }

  for (uint32_t i = 0; i < tries; i++) {
    FX_VLOGS(1) << "Updating system time, attempt: " << i + 1;
    auto ret = server->GetTimeFromServer();
    if (ret.first == NETWORK_ERROR) {
      if (i != tries - 1) {
        FX_VLOGS(1) << "Can't get time, sleeping for 1 sec";
        sleep(1);
      } else {
        FX_LOGS(ERROR) << "Can't get time due to network error after " << tries
                       << " attempts, abort";
        return false;
      }
      continue;
    } else if (ret.first != OK || !ret.second) {
      FX_LOGS(ERROR) << "Error with roughtime server [" << ret.first
                     << "], abort";
      return false;
    }
    if (SetSystemTime(rtc_service_path_, *ret.second)) {
      return true;
    }
  }
  FX_LOGS(ERROR) << "Inexplicably failed to get time after " << tries
                 << " attempts, abort";
  return false;
}

bool Timezone::SetSystemTime(const std::string& rtc_service_path,
                             zx::time_utc time) {
  int64_t epoch_seconds = time.get() / 1'000'000'000;
  struct tm ptm;
  gmtime_r(&epoch_seconds, &ptm);
  const rtc::Time rtc_time = ToRtcTime(&ptm);

  rtc::DeviceSyncPtr rtc_device_ptr;
  zx_status_t status =
      fdio_service_connect(rtc_service_path.c_str(),
                           rtc_device_ptr.NewRequest().TakeChannel().release());

  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Couldn't open RTC service at " << rtc_service_path
                   << ": " << strerror(errno);
    return false;
  }

  zx_status_t set_status;
  status = rtc_device_ptr->Set(rtc_time, &set_status);
  if ((status != ZX_OK) || (set_status != ZX_OK)) {
    FX_LOGS(ERROR) << "rtc::DeviceSyncPtr->Set failed: " << status << "/"
                   << set_status << " for " << ToIso8601String(epoch_seconds)
                   << " (" << epoch_seconds << ")";
    return false;
  }
  FX_LOGS(INFO) << "time set to: " << ToIso8601String(epoch_seconds);
  return true;
}

}  // namespace time_server
