// 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 <fuchsia/testing/llcpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/zx/port.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/port.h>

#include <thread>

#include <src/lib/fxl/logging.h>

namespace fake_clock = llcpp::fuchsia::testing;

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) {
        FXL_LOG(ERROR) << "Failed to create channel to FakeClock service";
        fake_clock.reset();
        return;
      }
      if (fdio_service_connect("/svc/fuchsia.testing.FakeClock", req.release()) != ZX_OK) {
        FXL_LOG(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(fake_clock::FakeClock::Call::RegisterEvent(GetService(), 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 = fake_clock::FakeClock::Call::Get(GetService());
  ZX_ASSERT(result.ok());
  return result.value().time;
}

__EXPORT zx_status_t zx_clock_get(zx_clock_t clock, zx_time_t* out) {
  if (clock == ZX_CLOCK_MONOTONIC) {
    *out = zx_clock_get_monotonic();
    return ZX_OK;
  } else {
    return _zx_clock_get(clock, out);
  }
}

__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(
      fake_clock::FakeClock::Call::RescheduleEvent(GetService(), 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(fake_clock::FakeClock::Call::CancelEvent(GetService(), std::move(e)).ok());
  return ZX_OK;
}
