// 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/fdio/directory.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/port.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/port.h>

#include <thread>

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

namespace fake_clock = fuchsia_testing;
namespace fake_clock_deadline = fuchsia_testing_deadline;

namespace {
zx::unowned_channel GetService() {
  static std::once_flag svc_connect_once;
  static zx::channel fake_clock;

  std::call_once(svc_connect_once, []() {
    if (!fake_clock.is_valid()) {
      zx::channel req;
      if (zx::channel::create(0, &fake_clock, &req) != ZX_OK) {
        FX_LOGS(ERROR) << "Failed to create channel to FakeClock service";
        fake_clock.reset();
        return;
      }
      if (fdio_service_connect("/svc/fuchsia.testing.FakeClock", req.release()) != ZX_OK) {
        FX_LOGS(ERROR) << "Failed to connect to fuchsia.testing.FakeClock service";
        fake_clock.reset();
        return;
      }
    }
  });
  return zx::unowned_channel(fake_clock);
}

zx::eventpair MakeEvent(zx_time_t deadline) {
  zx::eventpair l, r;
  ZX_ASSERT(zx::eventpair::create(0, &l, &r) == ZX_OK);
  ZX_ASSERT(fidl::WireCall<fake_clock::FakeClock>(GetService())
                ->RegisterEvent(std::move(r), deadline)
                .ok());
  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() {
  auto result = fidl::WireCall<fake_clock::FakeClock>(GetService())->Get();
  ZX_ASSERT(result.ok());
  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) {
  auto e = MakeEvent(deadline);
  ZX_ASSERT(_zx_object_wait_one(e.get(), ZX_EVENTPAIR_SIGNALED, ZX_TIME_INFINITE, nullptr) ==
            ZX_OK);
  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);
  }
  auto e = MakeEvent(deadline);
  zx_wait_item_t items[] = {{.handle = e.get(), .waitfor = ZX_EVENTPAIR_SIGNALED, .pending = 0},
                            {.handle = handle, .waitfor = signals, .pending = 0}};

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

// 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);
  } else 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;
    ZX_ASSERT(zx::port::create(0, &port) == ZX_OK);
    zx_status_t status;
    for (size_t i = 0; i < num_items; i++) {
      if ((status = zx_object_wait_async(items[i].handle, port.get(), i, items[i].waitfor, 0)) !=
          ZX_OK) {
        return status;
      }
    }
    auto event = MakeEvent(deadline);
    ZX_ASSERT(zx_object_wait_async(event.get(), port.get(), num_items, ZX_EVENTPAIR_SIGNALED, 0) ==
              ZX_OK);

    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 {
        auto* item = &items[packet.key];
        item->pending = packet.signal.observed;
      }
      return false;
    };

    zx_port_packet_t packet;
    if ((status = port.wait(zx::time::infinite(), &packet)) != 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;
  } else {
    // 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];
    memcpy(tmp, items, num_items * sizeof(zx_wait_item_t));
    auto event = MakeEvent(deadline);
    tmp[num_items].pending = 0;
    tmp[num_items].waitfor = ZX_EVENTPAIR_SIGNALED;
    tmp[num_items].handle = event.get();
    auto status = _zx_object_wait_many(tmp, num_items + 1, ZX_TIME_INFINITE);
    // copy everything back:
    memcpy(items, tmp, num_items * sizeof(zx_wait_item_t));
    if (status != ZX_OK || (tmp[num_items].pending & ZX_EVENTPAIR_SIGNALED) == 0) {
      return status;
    } else {
      return ZX_ERR_TIMED_OUT;
    }
  }
}

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

  auto event = MakeEvent(deadline);
  uint64_t key = 0xFACEFACE00000000 | event.get();
  ZX_ASSERT(zx_object_wait_async(event.get(), handle, key, ZX_EVENTPAIR_SIGNALED, 0) == ZX_OK);
  zx_port_packet_t tmp;
  auto status = _zx_port_wait(handle, ZX_TIME_INFINITE, &tmp);
  // always cancel the wait in case it wasn't a timeout
  zx_port_cancel(handle, event.get(), key);
  if (status != ZX_OK) {
    return status;
  } else if (tmp.type == ZX_PKT_TYPE_SIGNAL_ONE && tmp.key == key &&
             tmp.signal.observed == ZX_EVENTPAIR_SIGNALED) {
    return ZX_ERR_TIMED_OUT;
  } else {
    *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;
  zx_status_t status;
  if ((status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, e.reset_and_get_address())) !=
      ZX_OK) {
    return status;
  }
  // reschedule the event with the fake clock service:
  ZX_ASSERT(fidl::WireCall<fake_clock::FakeClock>(GetService())
                ->RescheduleEvent(std::move(e), deadline)
                .ok());
  return ZX_OK;
}

__EXPORT zx_status_t zx_timer_cancel(zx_handle_t handle) {
  zx::eventpair e;
  zx_status_t status;
  if ((status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, e.reset_and_get_address())) !=
      ZX_OK) {
    return status;
  }
  ZX_ASSERT(fidl::WireCall<fake_clock::FakeClock>(GetService())->CancelEvent(std::move(e)).ok());
  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) {
  fake_clock_deadline::wire::DeadlineId id;
  id.component_id = fidl::StringView::FromExternal(component, component_len);
  id.code = fidl::StringView::FromExternal(code, code_len);
  auto result = fidl::WireCall<fake_clock::FakeClock>(GetService())
                    ->CreateNamedDeadline(std::move(id), duration);
  ZX_ASSERT(result.ok());
  *out = result.value().deadline;
  return true;
}
