// 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(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:
  // Does not take ownership of inspector.
  explicit InspectMetrics(inspect::Inspector* inspector)
      : inspector_(inspector),
        root_(inspector_->GetRoot()),
        metrics_(root_.CreateChild("os")),
        dst_status_(metrics_.CreateInt("dst_status", kUninitialized)),
        tz_data_status_(metrics_.CreateInt("tz_data_status", kUninitialized)),
        tz_data_close_status_(
            metrics_.CreateInt("tz_data_close_status", kUninitialized)),
        get_profile_status_(
            metrics_.CreateInt("get_profile_status", kUninitialized)),
        profiles_timezone_content_status_(
            metrics_.CreateInt("timezone_content_status", kOk)),
        num_get_profile_calls_(metrics_.CreateInt("num_get_profile_calls", 0)),
        num_on_change_calls_(metrics_.CreateInt("num_on_change_calls", 0)),
        num_intl_provider_errors_(
            metrics_.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 inspector that all metrics are being reported into.
  inspect::Inspector* inspector_;

  // References inspector_ state.
  inspect::Node& root_;

  // The OS metrics node.
  inspect::Node metrics_;

  // 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<const std::string> timezone_names;

// Initialized on OS:Init(), deinitialized on OS::Cleanup.
std::unique_ptr<sys::ComponentInspector> component_inspector;
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;
}

// 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;
}

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

// 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);
  }

  sys::ComponentContext* context = dart::ComponentContext();
  component_inspector = std::make_unique<sys::ComponentInspector>(context);
  metrics = std::make_shared<InspectMetrics>(component_inspector->inspector());

  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();
  component_inspector.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(HOST_OS_FUCHSIA)
