// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <inttypes.h>
#include <lib/counters.h>
#include <lib/crypto/global_prng.h>
#include <lib/syscalls/forward.h>
#include <lib/user_copy/user_ptr.h>
#include <platform.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <trace.h>
#include <zircon/errors.h>
#include <zircon/syscalls/log.h>
#include <zircon/syscalls/policy.h>
#include <zircon/types.h>

#include <explicit-memory/bytes.h>
#include <fbl/alloc_checker.h>
#include <fbl/ref_ptr.h>
#include <kernel/auto_lock.h>
#include <kernel/thread.h>
#include <ktl/algorithm.h>
#include <ktl/atomic.h>
#include <object/event_dispatcher.h>
#include <object/event_pair_dispatcher.h>
#include <object/handle.h>
#include <object/log_dispatcher.h>
#include <object/process_dispatcher.h>
#include <object/resource.h>
#include <object/thread_dispatcher.h>

#include <ktl/enforce.h>

#define LOCAL_TRACE 0

KCOUNTER(syscalls_zx_ticks_get, "syscalls.zx_ticks_get")
KCOUNTER(syscalls_zx_clock_get_monotonic, "syscalls.zx_clock_get_monotonic")
KCOUNTER(syscalls_zx_nanosleep, "syscalls.zx_nanosleep")
KCOUNTER(syscalls_zx_nanosleep_zero_duration, "syscalls.zx_nanosleep_zero_duration")

constexpr size_t kMaxCPRNGDraw = ZX_CPRNG_DRAW_MAX_LEN;
constexpr size_t kMaxCPRNGSeed = ZX_CPRNG_ADD_ENTROPY_MAX_LEN;

// zx_status_t zx_nanosleep
zx_status_t sys_nanosleep(zx_time_t deadline) {
  LTRACEF("nseconds %" PRIi64 "\n", deadline);
  kcounter_add(syscalls_zx_nanosleep, 1);

  if (deadline <= 0) {
    kcounter_add(syscalls_zx_nanosleep_zero_duration, 1);
    return ZX_OK;
  }

  const zx_time_t now = current_time();
  const auto up = ProcessDispatcher::GetCurrent();
  const Deadline slackDeadline(deadline, up->GetTimerSlackPolicy());

  ThreadDispatcher::AutoBlocked by(ThreadDispatcher::Blocked::SLEEPING);

  // This syscall is declared as "blocking", so a higher layer will automatically
  // retry if we return ZX_ERR_INTERNAL_INTR_RETRY.
  return Thread::Current::SleepEtc(slackDeadline, Interruptible::Yes, now);
}

zx_time_t sys_clock_get_monotonic_via_kernel() {
  kcounter_add(syscalls_zx_clock_get_monotonic, 1);
  return current_time();
}

zx_ticks_t sys_ticks_get_via_kernel() {
  kcounter_add(syscalls_zx_ticks_get, 1);
  return current_ticks();
}

// zx_status_t zx_event_create
zx_status_t sys_event_create(uint32_t options, zx_handle_t* out) {
  LTRACEF("options 0x%x\n", options);

  if (options != 0u)
    return ZX_ERR_INVALID_ARGS;

  auto up = ProcessDispatcher::GetCurrent();
  zx_status_t res = up->EnforceBasicPolicy(ZX_POL_NEW_EVENT);
  if (res != ZX_OK)
    return res;

  KernelHandle<EventDispatcher> kernel_handle;
  zx_rights_t rights;

  zx_status_t result = EventDispatcher::Create(options, &kernel_handle, &rights);
  if (result != ZX_OK) {
    return result;
  }
  return up->MakeAndAddHandle(ktl::move(kernel_handle), rights, out);
}

// zx_status_t zx_eventpair_create
zx_status_t sys_eventpair_create(uint32_t options, zx_handle_t* out0, zx_handle_t* out1) {
  if (options != 0u)  // No options defined/supported yet.
    return ZX_ERR_NOT_SUPPORTED;

  auto up = ProcessDispatcher::GetCurrent();
  zx_status_t res = up->EnforceBasicPolicy(ZX_POL_NEW_EVENTPAIR);
  if (res != ZX_OK)
    return res;

  KernelHandle<EventPairDispatcher> handle0, handle1;
  zx_rights_t rights;
  zx_status_t result = EventPairDispatcher::Create(&handle0, &handle1, &rights);

  if (result == ZX_OK)
    result = up->MakeAndAddHandle(ktl::move(handle0), rights, out0);
  if (result == ZX_OK)
    result = up->MakeAndAddHandle(ktl::move(handle1), rights, out1);

  return result;
}

// zx_status_t zx_debuglog_create
zx_status_t sys_debuglog_create(zx_handle_t rsrc, uint32_t options, zx_handle_t* out) {
  LTRACEF("options 0x%x\n", options);
  // To support allowing the libc dynamic linker to emit log messages even
  // before process bootstrap is complete, we allow creating a debuglog with
  // options == 0 (write-only) without yet having a valid `rsrc` handle.
  // Otherwise, we should require a valid `rsrc` handle.
  // Inversely: if a resource handle is given, or if `options` is nonzero,
  // require that `rsrc` be a valid debuglog resource handle.
  if (rsrc != ZX_HANDLE_INVALID) {
    if (zx_status_t status = validate_resource_kind_base(rsrc, ZX_RSRC_KIND_SYSTEM,
                                                         ZX_RSRC_SYSTEM_DEBUGLOG_BASE) != ZX_OK)
      return status;
  } else {
    if (options != 0)
      return ZX_ERR_BAD_HANDLE;
  }

  // Ensure only valid options were given provided. The only valid flag is currently
  // ZX_LOG_FLAGS_READABLE.
  if ((options & ZX_LOG_FLAG_READABLE) != options) {
    return ZX_ERR_INVALID_ARGS;
  }

  // create a Log dispatcher
  KernelHandle<LogDispatcher> handle;
  zx_rights_t rights;
  zx_status_t result = LogDispatcher::Create(options, &handle, &rights);
  if (result != ZX_OK)
    return result;

  // by default log objects are write-only
  // as readable logs are more expensive
  if (options & ZX_LOG_FLAG_READABLE) {
    rights |= ZX_RIGHT_READ;
  }

  // create a handle and attach the dispatcher to it
  return ProcessDispatcher::GetCurrent()->MakeAndAddHandle(ktl::move(handle), rights, out);
}

// zx_status_t zx_debuglog_write
zx_status_t sys_debuglog_write(zx_handle_t log_handle, uint32_t options,
                               user_in_ptr<const void> ptr, size_t len) {
  LTRACEF("log handle %x, opt %x, ptr 0x%p, len %zu\n", log_handle, options, ptr.get(), len);

  len = len > DLOG_MAX_DATA ? DLOG_MAX_DATA : len;

  if (options & (~ZX_LOG_FLAGS_MASK))
    return ZX_ERR_INVALID_ARGS;

  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<LogDispatcher> log;
  zx_status_t status =
      up->handle_table().GetDispatcherWithRights(*up, log_handle, ZX_RIGHT_WRITE, &log);
  if (status != ZX_OK)
    return status;

  char buf[DLOG_MAX_RECORD];
  if (ptr.reinterpret<const char>().copy_array_from_user(buf, len) != ZX_OK)
    return ZX_ERR_INVALID_ARGS;

  return log->Write(DEBUGLOG_INFO, options, {buf, len});
}

// Converts a dlog_record_t into a zx_log_record_t and copies it out to user memory.
//
// Copies at most |len| bytes to |dst|.
static zx::result<size_t> CopyOutLogRecord(const dlog_record_t& internal_record,
                                           user_out_ptr<zx_log_record_t> dst, size_t len) {
  zx_log_record_t external_record{};
  external_record.sequence = internal_record.hdr.sequence;
  external_record.datalen = internal_record.hdr.datalen;
  external_record.severity = internal_record.hdr.severity;
  external_record.flags = internal_record.hdr.flags;
  external_record.timestamp = internal_record.hdr.timestamp;
  external_record.pid = internal_record.hdr.pid;
  external_record.tid = internal_record.hdr.tid;

  // The user's buffer may not be large enough to hold the zx_log_record_t let
  // alone the flexible array member that follows.
  //
  //
  zx_status_t status;
  if (len < sizeof(zx_log_record_t)) {
    // Not enough space to copy the whole struct so we must treat it as an array
    // of bytes instead.
    size_t to_copy = ktl::min(len, sizeof(external_record));
    auto src = reinterpret_cast<const char*>(&external_record);
    status = dst.reinterpret<char>().copy_array_to_user(src, to_copy);
    if (status == ZX_OK) {
      return zx::ok(to_copy);
    }
    return zx::error(status);
  }

  // There's enough space for the struct so copy it as is.  By not casting to an
  // array, we benefit from user_copy's static_asserts that verify the type
  // (zx_log_record_t) is ABI-safe.
  status = dst.copy_to_user(external_record);
  if (status != ZX_OK) {
    return zx::error(status);
  }
  size_t amount_copied = sizeof(external_record);
  len -= amount_copied;

  // Copy out as much of the flexible array member as will fit.
  size_t to_copy = ktl::min(len, static_cast<size_t>(external_record.datalen));
  status = dst.reinterpret<char>()
               .byte_offset(amount_copied)
               .copy_array_to_user(internal_record.data, to_copy);
  if (status != ZX_OK) {
    return zx::error(status);
  }
  amount_copied += to_copy;

  return zx::ok(amount_copied);
}

// zx_status_t zx_debuglog_read
zx_status_t sys_debuglog_read(zx_handle_t log_handle, uint32_t options, user_out_ptr<void> ptr,
                              size_t len) {
  LTRACEF("log handle %x, opt %x, ptr 0x%p, len %zu\n", log_handle, options, ptr.get(), len);

  if (options != 0)
    return ZX_ERR_INVALID_ARGS;

  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<LogDispatcher> log;
  zx_status_t status =
      up->handle_table().GetDispatcherWithRights(*up, log_handle, ZX_RIGHT_READ, &log);
  if (status != ZX_OK)
    return status;

  dlog_record_t record{};
  size_t actual;
  if ((status = log->Read(options, &record, &actual)) < 0) {
    return status;
  }

  zx::result<size_t> result = CopyOutLogRecord(record, ptr.reinterpret<zx_log_record_t>(), len);
  if (result.is_error()) {
    return result.error_value();
  }

  return static_cast<zx_status_t>(result.value());
}

// zx_status_t zx_cprng_draw_once
zx_status_t sys_cprng_draw_once(user_out_ptr<void> buffer, size_t len) {
  if (len > kMaxCPRNGDraw)
    return ZX_ERR_INVALID_ARGS;

  uint8_t kernel_buf[kMaxCPRNGDraw];
  // Ensure we get rid of the stack copy of the random data as this function returns.
  explicit_memory::ZeroDtor<uint8_t> zero_guard(kernel_buf, sizeof(kernel_buf));

  auto prng = crypto::global_prng::GetInstance();
  ASSERT(prng->is_thread_safe());
  prng->Draw(kernel_buf, len);

  if (buffer.reinterpret<uint8_t>().copy_array_to_user(kernel_buf, len) != ZX_OK)
    return ZX_ERR_INVALID_ARGS;
  return ZX_OK;
}

// zx_status_t zx_cprng_add_entropy
zx_status_t sys_cprng_add_entropy(user_in_ptr<const void> buffer, size_t buffer_size) {
  if (buffer_size > kMaxCPRNGSeed)
    return ZX_ERR_INVALID_ARGS;

  uint8_t kernel_buf[kMaxCPRNGSeed];
  // Ensure we get rid of the stack copy of the entropy as this function
  // returns.
  explicit_memory::ZeroDtor<uint8_t> zero_guard(kernel_buf, sizeof(kernel_buf));

  if (buffer.reinterpret<const uint8_t>().copy_array_from_user(kernel_buf, buffer_size) != ZX_OK)
    return ZX_ERR_INVALID_ARGS;

  auto prng = crypto::global_prng::GetInstance();
  ASSERT(prng->is_thread_safe());
  prng->AddEntropy(kernel_buf, buffer_size);

  return ZX_OK;
}
