// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/globals.h"
#if defined(DART_HOST_OS_FUCHSIA)

#include "vm/os.h"

#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include <fuchsia/intl/cpp/fidl.h>
#include <lib/async-loop/default.h>
#include <lib/async-loop/loop.h>
#include <lib/async/default.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/sys/inspect/cpp/component.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/threads.h>
#include <zircon/time.h>
#include <zircon/types.h>

#include <set>

#include "unicode/errorcode.h"
#include "unicode/timezone.h"
#include "unicode/umachine.h"

#include "platform/assert.h"
#include "platform/syslog.h"
#include "platform/utils.h"
#include "vm/lockers.h"
#include "vm/os_thread.h"
#include "vm/zone.h"

namespace {

using dart::Mutex;
using dart::MutexLocker;
using dart::Syslog;
using dart::Zone;

// This is the default timezone returned if it could not be obtained.  For
// Fuchsia, the default device timezone is always UTC.
static const char kDefaultTimezone[] = "UTC";

static constexpr int32_t kMsPerSec = 1000;

// The data directory containing ICU timezone data files.
static constexpr char kICUTZDataDir[] = "/config/data/tzdata/icu/44/le";

// This is the general OK status.
static constexpr int32_t kOk = 0;

// This status means that the error code is not initialized yet ("set" was not
// yet called).  Error codes are usually either 0 (kOk), or negative.
static constexpr int32_t kUninitialized = 1;

// The status codes for tzdata file open and read.
enum class TZDataStatus {
  // The operation completed without error.
  OK = 0,
  // The open call for the tzdata file did not succeed.
  COULD_NOT_OPEN = -1,
  // The close call (after tzdata was loaded) did not succeed.
  COULD_NOT_CLOSE = -2,
};

// Adds a facility for introspecting timezone data errors.  Allows insight into
// the internal state of the VM even if error reporting facilities fail.
//
// Under normal operation, all metric values below should be zero.
class InspectMetrics {
 public:
  // Takes ownership of the vm_node.
  explicit InspectMetrics(std::unique_ptr<inspect::Node> vm_node)
      : vm_node_(std::move(vm_node)),
        dst_status_(vm_node_->CreateInt("dst_status", kUninitialized)),
        tz_data_status_(vm_node_->CreateInt("tz_data_status", kUninitialized)),
        tz_data_close_status_(
            vm_node_->CreateInt("tz_data_close_status", kUninitialized)),
        get_profile_status_(
            vm_node_->CreateInt("get_profile_status", kUninitialized)),
        profiles_timezone_content_status_(
            vm_node_->CreateInt("timezone_content_status", kOk)),
        num_get_profile_calls_(vm_node_->CreateInt("num_get_profile_calls", 0)),
        num_on_change_calls_(vm_node_->CreateInt("num_on_change_calls", 0)),
        num_intl_provider_errors_(
            vm_node_->CreateInt("num_intl_provider_errors", 0)) {}

  // Registers a single call to GetProfile callback.
  void RegisterGetProfileCall() { num_get_profile_calls_.Add(1); }

  // Registers a single call to OnChange callback.
  void RegisterOnChangeCall() { num_on_change_calls_.Add(1); }

  // Registers a provider error.
  void RegisterIntlProviderError() { num_intl_provider_errors_.Add(1); }

  // Sets the last status code for DST offset calls.
  void SetDSTOffsetStatus(zx_status_t status) {
    dst_status_.Set(static_cast<int32_t>(status));
  }

  // Sets the return value of call to InitializeTZData, and the status of the
  // reported by close() on tzdata files.
  void SetInitTzData(TZDataStatus value, int32_t status) {
    tz_data_status_.Set(static_cast<int32_t>(value));
    tz_data_close_status_.Set(status);
  }

  // Sets the last status code for the call to PropertyProvider::GetProfile.
  void SetProfileStatus(zx_status_t status) {
    get_profile_status_.Set(static_cast<int32_t>(status));
  }

  // Sets the last status seen while examining timezones returned from
  // PropertyProvider::GetProfile.
  void SetTimeZoneContentStatus(zx_status_t status) {
    profiles_timezone_content_status_.Set(static_cast<int32_t>(status));
  }

 private:
  // The OS metrics node.
  std::unique_ptr<inspect::Node> vm_node_;

  // The status of the last GetTimeZoneOffset call.
  inspect::IntProperty dst_status_;

  // The status of the initialization.
  inspect::IntProperty tz_data_status_;

  // The return code for the close() call for tzdata files.
  inspect::IntProperty tz_data_close_status_;

  // The return code of the GetProfile call in GetTimeZoneName.  If this is
  // nonzero, then os_fuchsia.cc reported a default timezone as a fallback.
  inspect::IntProperty get_profile_status_;

  // U_ILLEGAL_ARGUMENT_ERROR(=1) if timezones read from ProfileProvider were
  // incorrect. Otherwise 0.  If this metric reports U_ILLEGAL_ARGUMENT_ERROR,
  // the os_fuchsia.cc module reported a default timezone as a fallback.
  inspect::IntProperty profiles_timezone_content_status_;

  // Keeps a number of get_profile update calls.
  inspect::IntProperty num_get_profile_calls_;

  // Number of "on change" callback calls.
  inspect::IntProperty num_on_change_calls_;

  // Keeps a number of errors encountered in intl provider.
  inspect::IntProperty num_intl_provider_errors_;
};

// Thread-safe storage for the current timezone name.
//
// Keeps an up to date timezone cache, updating if needed through the
// asynchronous update interface.  Access to this class is thread-safe.
class TimezoneName final {
 public:
  // Creates a new instance of TimezoneName.  Does not take ownership of
  // metrics.
  static std::shared_ptr<TimezoneName> New(
      fuchsia::intl::PropertyProviderPtr proxy,
      std::weak_ptr<InspectMetrics> metrics) {
    auto timezone_name =
        std::make_shared<TimezoneName>(std::move(proxy), metrics);
    timezone_name->InitHandlers(timezone_name);
    return timezone_name;
  }

  TimezoneName(fuchsia::intl::PropertyProviderPtr proxy,
               std::weak_ptr<InspectMetrics> metrics)
      : m_(),
        metrics_(std::move(metrics)),
        proxy_(std::move(proxy)),
        timezone_name_(kDefaultTimezone) {
    ASSERT(metrics_.lock() != nullptr);
  }

  // Gets the current timezone name.  Repeated calls may retrieve updated
  // values.
  std::string Get() const {
    MutexLocker lock(&m_);
    // Returns a copy, to avoid a data race with async updates.
    return timezone_name_;
  }

 private:
  // Sets the event handlers in this resolver.  Intended to resolve a circular
  // reference between the shared timezone name and this.
  void InitHandlers(std::shared_ptr<TimezoneName> timezone_name) {
    ASSERT(timezone_name.get() == this);
    timezone_name->proxy_.set_error_handler(
        [weak_this =
             std::weak_ptr<TimezoneName>(timezone_name)](zx_status_t status) {
          if (!weak_this.expired()) {
            weak_this.lock()->ErrorHandler(status);
          }
        });
    timezone_name->proxy_.events().OnChange =
        [weak_this = std::weak_ptr<TimezoneName>(timezone_name)]() {
          if (!weak_this.expired()) {
            weak_this.lock()->OnChangeCallback();
          }
        };
    timezone_name->proxy_->GetProfile(
        [weak_this = std::weak_ptr<TimezoneName>(timezone_name)](
            fuchsia::intl::Profile profile) {
          if (!weak_this.expired()) {
            weak_this.lock()->GetProfileCallback(std::move(profile));
          }
        });
  }

  // Called on a profile provider error in the context of the event loop
  // thread.
  void ErrorHandler(zx_status_t status) {
    MutexLocker lock(&m_);
    WithMetrics([status](std::shared_ptr<InspectMetrics> metrics) {
      metrics->SetProfileStatus(status);
      metrics->RegisterIntlProviderError();
    });
  }

  // Called when an OnChange event is received in the context of the event loop
  // thread.  The only action here is to trigger an asynchronous update of the
  // intl profile.
  void OnChangeCallback() {
    MutexLocker lock(&m_);
    WithMetrics([](std::shared_ptr<InspectMetrics> metrics) {
      metrics->RegisterOnChangeCall();
    });
    proxy_->GetProfile([this](fuchsia::intl::Profile profile) {
      this->GetProfileCallback(std::move(profile));
    });
  }

  // Called when a GetProfile async request is resolved, in the context of the
  // event loop thread.
  void GetProfileCallback(fuchsia::intl::Profile profile) {
    MutexLocker lock(&m_);
    WithMetrics([](std::shared_ptr<InspectMetrics> metrics) {
      metrics->RegisterGetProfileCall();
    });
    const std::vector<fuchsia::intl::TimeZoneId>& timezones =
        profile.time_zones();
    if (timezones.empty()) {
      WithMetrics([](std::shared_ptr<InspectMetrics> metrics) {
        metrics->SetTimeZoneContentStatus(U_ILLEGAL_ARGUMENT_ERROR);
      });
      // Empty timezone array is not up to fuchsia::intl spec.  The serving
      // endpoint is broken and should be fixed.
      Syslog::PrintErr("got empty timezone value\n");
      return;
    }
    WithMetrics([](std::shared_ptr<InspectMetrics> metrics) {
      metrics->SetProfileStatus(ZX_OK);
      metrics->SetTimeZoneContentStatus(ZX_OK);
    });

    timezone_name_ = timezones[0].id;
  }

  // Runs the provided function only on valid metrics.
  void WithMetrics(std::function<void(std::shared_ptr<InspectMetrics> m)> f) {
    std::shared_ptr<InspectMetrics> l = metrics_.lock();
    if (l != nullptr) {
      f(l);
    }
  }

  // Guards timezone_name_ because the callbacks will be called in an
  // asynchronous thread.
  mutable Mutex m_;

  // Used to keep tally on the update events. Not owned.
  std::weak_ptr<InspectMetrics> metrics_;

  // A client-side proxy for a connection to the property provider service.
  fuchsia::intl::PropertyProviderPtr proxy_;

  // Caches the current timezone name.  This is updated asynchronously through
  // GetProfileCallback.
  std::string timezone_name_;
};

// The timezone names encountered so far.  The timezone names must live forever.
std::set<std::string> timezone_names;

// Initialized on OS:Init(), deinitialized on OS::Cleanup.
std::shared_ptr<InspectMetrics> metrics;
std::shared_ptr<TimezoneName> timezone_name;
async_loop_t* message_loop = nullptr;

// Initializes the source of timezone data if available.  Timezone data file in
// Fuchsia is at a fixed directory path.  Returns true on success.
bool InitializeTZData() {
  ASSERT(metrics != nullptr);
  // Try opening the path to check if present.  No need to verify that it is a
  // directory since ICU loading will return an error if the TZ data path is
  // wrong.
  int fd = openat(AT_FDCWD, kICUTZDataDir, O_RDONLY);
  if (fd < 0) {
    metrics->SetInitTzData(TZDataStatus::COULD_NOT_OPEN, fd);
    return false;
  }
  // 0 == Not overwriting the env var if already set.
  setenv("ICU_TIMEZONE_FILES_DIR", kICUTZDataDir, 0);
  int32_t close_status = close(fd);
  if (close_status != 0) {
    metrics->SetInitTzData(TZDataStatus::COULD_NOT_CLOSE, close_status);
    return false;
  }
  metrics->SetInitTzData(TZDataStatus::OK, 0);
  return true;
}

int64_t GetCurrentTimeNanos() {
  struct timespec ts;
  if (timespec_get(&ts, TIME_UTC) == 0) {
    FATAL("timespec_get failed");
    return 0;
  }
  return zx_time_add_duration(ZX_SEC(ts.tv_sec), ZX_NSEC(ts.tv_nsec));
}

}  // namespace

namespace dart {

#ifndef PRODUCT

DEFINE_FLAG(bool,
            generate_perf_events_symbols,
            false,
            "Generate events symbols for profiling with perf");

#endif  // !PRODUCT

const char* OS::Name() {
  return "fuchsia";
}

intptr_t OS::ProcessId() {
  return static_cast<intptr_t>(getpid());
}

// TODO(FL-98): Change this to talk to fuchsia.dart to get timezone service to
// directly get timezone.
//
// Putting this hack right now due to CP-120 as I need to remove
// component:ConnectToEnvironmentServices and this is the only thing that is
// blocking it and FL-98 will take time.
static fuchsia::intl::PropertyProviderPtr property_provider;

static zx_status_t GetLocalAndDstOffsetInSeconds(int64_t seconds_since_epoch,
                                                 int32_t* local_offset,
                                                 int32_t* dst_offset) {
  const char* timezone_id = OS::GetTimeZoneName(seconds_since_epoch);
  std::unique_ptr<icu::TimeZone> timezone(
      icu::TimeZone::createTimeZone(timezone_id));
  UErrorCode error = U_ZERO_ERROR;
  const auto ms_since_epoch =
      static_cast<UDate>(kMsPerSec * seconds_since_epoch);
  // The units of time that local_offset and dst_offset are returned from this
  // function is, usefully, not documented, but it seems that the units are
  // milliseconds.  Add these variables here for clarity.
  int32_t local_offset_ms = 0;
  int32_t dst_offset_ms = 0;
  timezone->getOffset(ms_since_epoch, /*local_time=*/0, local_offset_ms,
                      dst_offset_ms, error);
  metrics->SetDSTOffsetStatus(error);
  if (error != U_ZERO_ERROR) {
    icu::ErrorCode icu_error;
    icu_error.set(error);
    Syslog::PrintErr("could not get DST offset: %s\n", icu_error.errorName());
    return ZX_ERR_INTERNAL;
  }
  // We must return offset in seconds, so convert.
  *local_offset = local_offset_ms / kMsPerSec;
  *dst_offset = dst_offset_ms / kMsPerSec;
  return ZX_OK;
}

// Returns a C string with the time zone name. This module retains the
// ownership of the pointer.
const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
  ASSERT(timezone_name != nullptr);

  // Sadly, since we do not know how long the timezone name will be needed, we
  // can not ever deallocate it. So instead, we put it into a a set that will
  // not move it around in memory and return a pointer to it.  Since the number
  // of timezones is finite, this ensures that the memory taken up by timezones
  // does not grow indefinitely, even if we end up retaining all the timezones
  // there are.
  const auto i = timezone_names.insert(timezone_name->Get());
  ASSERT(i.first != timezone_names.end());
  return i.first->c_str();
}

int OS::GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch) {
  int32_t local_offset = 0;
  int32_t dst_offset = 0;
  const zx_status_t status = GetLocalAndDstOffsetInSeconds(
      seconds_since_epoch, &local_offset, &dst_offset);
  return status == ZX_OK ? local_offset + dst_offset : 0;
}

int OS::GetLocalTimeZoneAdjustmentInSeconds() {
  int32_t local_offset, dst_offset;
  int64_t now_seconds = GetCurrentTimeNanos() / ZX_SEC(1);
  zx_status_t status =
      GetLocalAndDstOffsetInSeconds(now_seconds, &local_offset, &dst_offset);
  return status == ZX_OK ? local_offset : 0;
}

int64_t OS::GetCurrentTimeMillis() {
  return GetCurrentTimeNanos() / ZX_MSEC(1);
}

int64_t OS::GetCurrentTimeMicros() {
  return GetCurrentTimeNanos() / ZX_USEC(1);
}

int64_t OS::GetCurrentMonotonicTicks() {
  return zx_clock_get_monotonic();
}

int64_t OS::GetCurrentMonotonicFrequency() {
  return kNanosecondsPerSecond;
}

int64_t OS::GetCurrentMonotonicMicros() {
  const int64_t ticks = GetCurrentMonotonicTicks();
  ASSERT(GetCurrentMonotonicFrequency() == kNanosecondsPerSecond);
  return ticks / kNanosecondsPerMicrosecond;
}

int64_t OS::GetCurrentThreadCPUMicros() {
  zx_info_thread_stats_t info = {};
  zx_status_t status = zx_object_get_info(thrd_get_zx_handle(thrd_current()),
                                          ZX_INFO_THREAD_STATS, &info,
                                          sizeof(info), nullptr, nullptr);
  return status == ZX_OK ? info.total_runtime / kNanosecondsPerMicrosecond : 0;
}

int64_t OS::GetCurrentMonotonicMicrosForTimeline() {
#if defined(SUPPORT_TIMELINE)
  return OS::GetCurrentMonotonicMicros();
#else
  return -1;
#endif
}

// On Fuchsia, thread timestamp values are not used in the tracing/timeline
// integration. Because of this, we try to avoid querying them, since doing so
// has both a runtime and trace buffer storage cost.
int64_t OS::GetCurrentThreadCPUMicrosForTimeline() {
  return -1;
}

// TODO(5411554):  May need to hoist these architecture dependent code
// into a architecture specific file e.g: os_ia32_fuchsia.cc
intptr_t OS::ActivationFrameAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) ||                   \
    defined(TARGET_ARCH_ARM64)
  const int kMinimumAlignment = 16;
#elif defined(TARGET_ARCH_ARM)
  const int kMinimumAlignment = 8;
#else
#error Unsupported architecture.
#endif
  intptr_t alignment = kMinimumAlignment;
  // TODO(5411554): Allow overriding default stack alignment for
  // testing purposes.
  // Flags::DebugIsInt("stackalign", &alignment);
  ASSERT(Utils::IsPowerOfTwo(alignment));
  ASSERT(alignment >= kMinimumAlignment);
  return alignment;
}

int OS::NumberOfAvailableProcessors() {
  return sysconf(_SC_NPROCESSORS_CONF);
}

void OS::Sleep(int64_t millis) {
  SleepMicros(millis * kMicrosecondsPerMillisecond);
}

void OS::SleepMicros(int64_t micros) {
  zx_nanosleep(zx_deadline_after(micros * kNanosecondsPerMicrosecond));
}

void OS::DebugBreak() {
  UNIMPLEMENTED();
}

DART_NOINLINE uintptr_t OS::GetProgramCounter() {
  return reinterpret_cast<uintptr_t>(
      __builtin_extract_return_addr(__builtin_return_address(0)));
}

void OS::Print(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VFPrint(stdout, format, args);
  va_end(args);
}

void OS::VFPrint(FILE* stream, const char* format, va_list args) {
  vfprintf(stream, format, args);
  fflush(stream);
}

char* OS::SCreate(Zone* zone, const char* format, ...) {
  va_list args;
  va_start(args, format);
  char* buffer = VSCreate(zone, format, args);
  va_end(args);
  return buffer;
}

char* OS::VSCreate(Zone* zone, const char* format, va_list args) {
  // Measure.
  va_list measure_args;
  va_copy(measure_args, args);
  intptr_t len = Utils::VSNPrint(NULL, 0, format, measure_args);
  va_end(measure_args);

  char* buffer;
  if (zone != nullptr) {
    buffer = zone->Alloc<char>(len + 1);
  } else {
    buffer = reinterpret_cast<char*>(malloc(len + 1));
  }
  ASSERT(buffer != NULL);

  // Print.
  va_list print_args;
  va_copy(print_args, args);
  Utils::VSNPrint(buffer, len + 1, format, print_args);
  va_end(print_args);
  return buffer;
}

bool OS::StringToInt64(const char* str, int64_t* value) {
  ASSERT(str != NULL && strlen(str) > 0 && value != NULL);
  int32_t base = 10;
  char* endptr;
  int i = 0;
  if (str[0] == '-') {
    i = 1;
  } else if (str[0] == '+') {
    i = 1;
  }
  if ((str[i] == '0') && (str[i + 1] == 'x' || str[i + 1] == 'X') &&
      (str[i + 2] != '\0')) {
    base = 16;
  }
  errno = 0;
  if (base == 16) {
    // Unsigned 64-bit hexadecimal integer literals are allowed but
    // immediately interpreted as signed 64-bit integers.
    *value = static_cast<int64_t>(strtoull(str, &endptr, base));
  } else {
    *value = strtoll(str, &endptr, base);
  }
  return ((errno == 0) && (endptr != str) && (*endptr == 0));
}

void OS::RegisterCodeObservers() {
#ifndef PRODUCT
  if (FLAG_generate_perf_events_symbols) {
    UNIMPLEMENTED();
  }
#endif  // !PRODUCT
}

void OS::PrintErr(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VFPrint(stderr, format, args);
  va_end(args);
}

void OS::Init() {
  if (async_get_default_dispatcher() == nullptr) {
    async_loop_create(&kAsyncLoopConfigAttachToCurrentThread, &message_loop);
    async_set_default_dispatcher(async_loop_get_dispatcher(message_loop));
    async_loop_start_thread(message_loop, "Fuchsia async loop", nullptr);
  }

  auto vm_node = dart::TakeDartVmNode();

  // TODO(fxbug.dev/69558) allow vm_node to be null and not crash
  ASSERT(vm_node != nullptr);
  metrics = std::make_shared<InspectMetrics>(std::move(vm_node));

  InitializeTZData();
  auto services = sys::ServiceDirectory::CreateFromNamespace();
  services->Connect(property_provider.NewRequest());

  timezone_name = TimezoneName::New(std::move(property_provider), metrics);
}

void OS::Cleanup() {
  if (message_loop != nullptr) {
    async_loop_shutdown(message_loop);
  }
  timezone_name.reset();
  metrics.reset();

  if (message_loop != nullptr) {
    // Check message_loop is still the default dispatcher before clearing it.
    if (async_get_default_dispatcher() ==
        async_loop_get_dispatcher(message_loop)) {
      async_set_default_dispatcher(nullptr);
    }
    async_loop_destroy(message_loop);
    message_loop = nullptr;
  }
}

void OS::PrepareToAbort() {}

void OS::Abort() {
  PrepareToAbort();
  abort();
}

void OS::Exit(int code) {
  exit(code);
}

}  // namespace dart

#endif  // defined(DART_HOST_OS_FUCHSIA)
