// Copyright 2019 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 <fidl/fuchsia.testing.deadline/cpp/wire.h>
#include <fidl/fuchsia.testing/cpp/wire.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/port.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/port.h>
#include <zircon/utc.h>

#include <thread>

#include <src/lib/fake-clock/named-timer/named_timer.h>

namespace fake_clock = fuchsia_testing;

namespace {
fidl::UnownedClientEnd<fake_clock::FakeClock> GetService() {
  static std::once_flag svc_connect_once;
  static fidl::ClientEnd<fake_clock::FakeClock> fake_clock;

  // Writing log messages almost anywhere here will crash the program. So,
  // we must do without logging. Also, any errors here will result in bizarre
  // low level stack traces, since the C runtime library calls into this code.
  std::call_once(svc_connect_once, []() {
    if (!fake_clock.is_valid()) {
      zx::result result = component::Connect<fake_clock::FakeClock>();
      if (result.is_error()) {
        FX_PLOGS(ERROR, result.status_value())
            << "Failed to connect to fuchsia.testing.FakeClock service";
      }
      fake_clock = std::move(result.value());
    }
  });
  return fake_clock.borrow();
}

zx::eventpair MakeEvent(zx_time_t deadline) {
  zx::eventpair l, r;
  if (zx_status_t status = zx::eventpair::create(0, &l, &r); status != ZX_OK) {
    ZX_PANIC("%s", zx_status_get_string(status));
  }
  const fidl::Status result = fidl::WireCall(GetService())->RegisterEvent(std::move(r), deadline);
  ZX_ASSERT_MSG(result.ok(), "%s", result.FormatDescription().c_str());
  return l;
}

}  // namespace

__EXPORT zx_status_t zx_futex_wait(const zx_futex_t* value_ptr, zx_futex_t current_value,
                                   zx_handle_t new_futex_owner, zx_time_t deadline) {
  ZX_ASSERT_MSG(deadline == ZX_TIME_INFINITE,
                "zx_futex_wait with deadline is currently supported by FakeClock library");
  return _zx_futex_wait(value_ptr, current_value, new_futex_owner, deadline);
}

__EXPORT zx_status_t zx_channel_call(zx_handle_t handle, uint32_t options, zx_time_t deadline,
                                     const zx_channel_call_args_t* args, uint32_t* actual_bytes,
                                     uint32_t* actual_handles) {
  // TODO(brunodalbo) There may be a way to get channel_call working if we create a temporary
  // channel and an auxiliary thread, but looks like most channel_call call sites don't define
  // deadlines.
  ZX_ASSERT_MSG(deadline == ZX_TIME_INFINITE,
                "zx_channel_call with deadline is not yet supported by FakeClock library");
  return _zx_channel_call(handle, options, deadline, args, actual_bytes, actual_handles);
}

__EXPORT zx_time_t zx_clock_get_monotonic() {
  const fidl::WireResult result = fidl::WireCall(GetService())->Get();
  ZX_ASSERT_MSG(result.ok(), "%s", result.FormatDescription().c_str());
  return result.value().time;
}

__EXPORT zx_time_t zx_deadline_after(zx_duration_t duration) {
  return zx_time_add_duration(zx_clock_get_monotonic(), duration);
}

__EXPORT zx_status_t zx_nanosleep(zx_time_t deadline) {
  zx::eventpair e = MakeEvent(deadline);
  if (zx_status_t status =
          _zx_object_wait_one(e.get(), ZX_EVENTPAIR_SIGNALED, ZX_TIME_INFINITE, nullptr) != ZX_OK) {
    ZX_PANIC("%s", zx_status_get_string(status));
  }
  return ZX_OK;
}

// wait_one is implemented by making it a wait_many on an infinite deadline with two items: one is
// the original handle+signals, the other is the eventpair created from the fake-clock service.
__EXPORT zx_status_t zx_object_wait_one(zx_handle_t handle, zx_signals_t signals,
                                        zx_time_t deadline, zx_signals_t* observed) {
  if (deadline == ZX_TIME_INFINITE || deadline == 0) {
    return _zx_object_wait_one(handle, signals, deadline, observed);
  }
  zx::eventpair e = MakeEvent(deadline);
  zx_wait_item_t items[] = {
      {
          .handle = e.get(),
          .waitfor = ZX_EVENTPAIR_SIGNALED,
      },
      {
          .handle = handle,
          .waitfor = signals,
      },
  };

  zx_status_t status = _zx_object_wait_many(items, 2, ZX_TIME_INFINITE);
  if (observed) {
    *observed = items[1].pending;
  }
  if (status != ZX_OK) {
    return status;
  }
  if ((items[0].pending & ZX_EVENTPAIR_SIGNALED) != 0) {
    return ZX_ERR_TIMED_OUT;
  }
  return ZX_OK;
}

// wait_many is implemented by adding an extra eventpair handle extracted from fake-clock to the
// wait list, and changing the deadline to infinite. If the number of items on the wait is already
// ZX_WAIT_MANY_MAX_ITEMS (meaning we can't add an extra item), we create a port instead and
// register all the wait items to it.
__EXPORT zx_status_t zx_object_wait_many(zx_wait_item_t* items, size_t num_items,
                                         zx_time_t deadline) {
  if (deadline == ZX_TIME_INFINITE || deadline == 0 || num_items > ZX_WAIT_MANY_MAX_ITEMS) {
    return _zx_object_wait_many(items, num_items, deadline);
  }
  if (num_items == ZX_WAIT_MANY_MAX_ITEMS) {
    // can't add a new item, we need to build a port and wait on it.
    zx::port port;
    if (zx_status_t status = zx::port::create(0, &port); status != ZX_OK) {
      ZX_PANIC("%s", zx_status_get_string(status));
    }
    for (size_t i = 0; i < num_items; i++) {
      if (zx_status_t status =
              zx::unowned_handle(items[i].handle)->wait_async(port, i, items[i].waitfor, 0);
          status != ZX_OK) {
        return status;
      }
    }
    zx::eventpair event = MakeEvent(deadline);
    if (zx_status_t status = event.wait_async(port, num_items, ZX_EVENTPAIR_SIGNALED, 0);
        status != ZX_OK) {
      ZX_PANIC("%s", zx_status_get_string(status));
    }

    auto update_item = [&items, num_items](const zx_port_packet& packet) {
      if (packet.key == num_items) {
        if (packet.signal.observed & ZX_EVENTPAIR_SIGNALED) {
          return true;
        }
      } else {
        items[packet.key].pending = packet.signal.observed;
      }
      return false;
    };

    zx_port_packet_t packet;
    if (zx_status_t status = port.wait(zx::time::infinite(), &packet); status != ZX_OK) {
      return status;
    }
    // update_item will return true if the first packet out of the port is a timeout.
    if (update_item(packet)) {
      return ZX_ERR_TIMED_OUT;
    }
    // many things may have happened at once, how we just keep polling the port with a zero deadline
    // and updating the items
    while (port.wait(zx::time(0), &packet) == ZX_OK) {
      if (update_item(packet)) {
        break;
      }
    }
    return ZX_OK;
  }
  // we can just add an extra item, but we'll need to copy all the wait items
  zx_wait_item_t tmp[ZX_WAIT_MANY_MAX_ITEMS];
  std::copy_n(items, num_items, tmp);
  zx::eventpair event = MakeEvent(deadline);
  tmp[num_items].pending = 0;
  tmp[num_items].waitfor = ZX_EVENTPAIR_SIGNALED;
  tmp[num_items].handle = event.get();
  zx_status_t status = _zx_object_wait_many(tmp, num_items + 1, ZX_TIME_INFINITE);
  // copy everything back:
  std::copy_n(tmp, num_items, items);
  if (status != ZX_OK) {
    return status;
  }
  if ((tmp[num_items].pending & ZX_EVENTPAIR_SIGNALED) != 0) {
    return ZX_ERR_TIMED_OUT;
  }

  return ZX_OK;
}

// port_wait adds an extra fake-clock eventpair handle to the port and changes the deadline to
// ZX_TIME_INFINITE.
__EXPORT zx_status_t zx_port_wait(zx_handle_t handle, zx_time_t deadline,
                                  zx_port_packet_t* packet) {
  if (deadline == ZX_TIME_INFINITE) {
    return _zx_port_wait(handle, deadline, packet);
  }

  zx::eventpair event = MakeEvent(deadline);
  uint64_t key = 0xFACEFACE00000000 | event.get();
  if (zx_status_t status = zx_object_wait_async(event.get(), handle, key, ZX_EVENTPAIR_SIGNALED, 0);
      status != ZX_OK) {
    ZX_PANIC("%s", zx_status_get_string(status));
  }
  zx_port_packet_t tmp;
  zx_status_t status = _zx_port_wait(handle, ZX_TIME_INFINITE, &tmp);
  // always cancel the wait in case it wasn't a timeout
  zx::unowned_port(handle)->cancel(event, key);
  if (status != ZX_OK) {
    return status;
  }
  if (tmp.type == ZX_PKT_TYPE_SIGNAL_ONE && tmp.key == key &&
      tmp.signal.observed == ZX_EVENTPAIR_SIGNALED) {
    return ZX_ERR_TIMED_OUT;
  }
  *packet = tmp;
  return ZX_OK;
}

// timer_create changes the type of returned handle from an actual timer to one side of an eventpair
// created by fake-clock. It relies on the fact that ZX_EVENTPAIR_SIGNALED is the same bit as
// ZX_TIMER_SIGNALED, meaning unless clients are inspecting the handle type, they shouldn't be able
// to tell the difference.
__EXPORT zx_status_t zx_timer_create(uint32_t options, zx_clock_t clock_id, zx_handle_t* out) {
  // We're replacing a timer with an event, and shamelessly using the fact that
  // ZX_EVENTPAIR_SIGNALED and ZX_TIMER_SIGNAL collide, this assertion protects that assumption more
  // strongly.
  static_assert(ZX_EVENTPAIR_SIGNALED == ZX_TIMER_SIGNALED);
  if (clock_id != ZX_CLOCK_MONOTONIC) {
    // NOTE: _zx_timer_create will just fail according to the docs.
    return _zx_timer_create(options, clock_id, out);
  }
  // Create an event with infinite deadline and return that instead of a timer handle
  *out = MakeEvent(ZX_TIME_INFINITE).release();
  return ZX_OK;
}

__EXPORT zx_status_t zx_timer_set(zx_handle_t handle, zx_time_t deadline, zx_duration_t slack) {
  zx::eventpair e;
  if (zx_status_t status = zx::unowned_eventpair(handle)->duplicate(ZX_RIGHT_SAME_RIGHTS, &e);
      status != ZX_OK) {
    return status;
  }
  // reschedule the event with the fake clock service:
  const fidl::WireResult result =
      fidl::WireCall(GetService())->RescheduleEvent(std::move(e), deadline);
  ZX_ASSERT_MSG(result.ok(), "%s", result.FormatDescription().c_str());
  return ZX_OK;
}

__EXPORT zx_status_t zx_timer_cancel(zx_handle_t handle) {
  zx::eventpair e;
  if (zx_status_t status = zx::unowned_eventpair(handle)->duplicate(ZX_RIGHT_SAME_RIGHTS, &e);
      status != ZX_OK) {
    return status;
  }
  const fidl::WireResult result = fidl::WireCall(GetService())->CancelEvent(std::move(e));
  ZX_ASSERT_MSG(result.ok(), "%s", result.FormatDescription().c_str());
  return ZX_OK;
}

__EXPORT bool create_named_deadline(char* component, size_t component_len, char* code,
                                    size_t code_len, zx_time_t duration, zx_time_t* out) {
  const fidl::WireResult result =
      fidl::WireCall(GetService())
          ->CreateNamedDeadline(
              {
                  .component_id = fidl::StringView::FromExternal(component, component_len),
                  .code = fidl::StringView::FromExternal(code, code_len),
              },
              duration);
  ZX_ASSERT_MSG(result.ok(), "%s", result.FormatDescription().c_str());
  *out = result.value().deadline;
  return true;
}

__EXPORT zx_handle_t zx_utc_reference_get() {
#ifdef FAKE_CLOCK_ALLOW_UTC
  return _zx_utc_reference_get();
#else
  FX_LOGS(FATAL) << "UTC clock may interact in unexpected ways with the fake-clock library. "
                 << "See //src/lib/fake-clock/README.md for ways to fix this.";
  return ZX_HANDLE_INVALID;
#endif  // FAKE_CLOCK_ALLOW_UTC
}
