// 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 <err.h>
#include <inttypes.h>
#include <lib/ktrace.h>
#include <trace.h>
#include <zircon/syscalls/policy.h>
#include <zircon/types.h>

#include <fbl/alloc_checker.h>
#include <fbl/ref_ptr.h>
#include <object/handle.h>
#include <object/port_dispatcher.h>
#include <object/process_dispatcher.h>

#include "priv.h"

#define LOCAL_TRACE 0

// zx_status_t zx_port_create
zx_status_t sys_port_create(uint32_t options, user_out_handle* out) {
  LTRACEF("options %u\n", options);
  auto up = ProcessDispatcher::GetCurrent();
  zx_status_t result = up->EnforceBasicPolicy(ZX_POL_NEW_PORT);
  if (result != ZX_OK)
    return result;

  KernelHandle<PortDispatcher> handle;
  zx_rights_t rights;

  result = PortDispatcher::Create(options, &handle, &rights);
  if (result != ZX_OK)
    return result;

  uint32_t koid = (uint32_t)handle.dispatcher()->get_koid();

  result = out->make(ktl::move(handle), rights);

  ktrace(TAG_PORT_CREATE, koid, 0, 0, 0);
  return result;
}

// zx_status_t zx_port_queue
zx_status_t sys_port_queue(zx_handle_t handle, user_in_ptr<const zx_port_packet_t> packet_in) {
  LTRACEF("handle %x\n", handle);

  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<PortDispatcher> port;
  zx_status_t status = up->GetDispatcherWithRights(handle, ZX_RIGHT_WRITE, &port);
  if (status != ZX_OK)
    return status;

  zx_port_packet_t packet;
  status = packet_in.copy_from_user(&packet);
  if (status != ZX_OK)
    return status;

  return port->QueueUser(packet);
}

// zx_status_t zx_port_wait
zx_status_t sys_port_wait(zx_handle_t handle, zx_time_t deadline,
                          user_out_ptr<zx_port_packet_t> packet_out) {
  LTRACEF("handle %x\n", handle);

  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<PortDispatcher> port;
  zx_status_t status = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &port);
  if (status != ZX_OK)
    return status;

  const Deadline slackDeadline(deadline, up->GetTimerSlackPolicy());

  ktrace(TAG_PORT_WAIT, (uint32_t)port->get_koid(), 0, 0, 0);

  zx_port_packet_t pp;
  zx_status_t st = port->Dequeue(slackDeadline, &pp);

  ktrace(TAG_PORT_WAIT_DONE, (uint32_t)port->get_koid(), st, 0, 0);

  if (st != ZX_OK)
    return st;

  status = packet_out.copy_to_user(pp);
  if (status != ZX_OK)
    return status;

  return ZX_OK;
}

// zx_status_t zx_port_cancel
zx_status_t sys_port_cancel(zx_handle_t handle, zx_handle_t source, uint64_t key) {
  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<PortDispatcher> port;
  zx_status_t status = up->GetDispatcherWithRights(handle, ZX_RIGHT_WRITE, &port);
  if (status != ZX_OK)
    return status;

  {
    Guard<BrwLockPi, BrwLockPi::Reader> guard{up->handle_table_lock()};
    Handle* watched = up->GetHandleLocked(source);
    if (!watched)
      return ZX_ERR_BAD_HANDLE;
    if (!watched->HasRights(ZX_RIGHT_WAIT))
      return ZX_ERR_ACCESS_DENIED;

    auto dispatcher = watched->dispatcher();
    if (!dispatcher->is_waitable())
      return ZX_ERR_NOT_SUPPORTED;

    bool had_observer = dispatcher->CancelByKey(watched, port.get(), key);
    bool packet_removed = port->CancelQueued(watched, key);
    return (had_observer || packet_removed) ? ZX_OK : ZX_ERR_NOT_FOUND;
  }
}
