// Copyright 2017 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <zircon/syscalls.h>
#include <zircon/syscalls/port.h>

#include <lib/fdio/unsafe.h>

#include <port/port.h>

#if TRACE_PORT_API
#define zprintf(fmt...) printf(fmt)
#else
#define zprintf(fmt...) do {} while (0)
#endif

zx_status_t port_init(port_t* port) {
    zx_status_t r = zx_port_create(0, &port->handle);
    zprintf("port_init(%p) port=%x\n", port, port->handle);
    return r;
}

zx_status_t port_wait(port_t* port, port_handler_t* ph) {
    zprintf("port_wait(%p, %p) obj=%x port=%x\n",
            port, ph, ph->handle, port->handle);
    return zx_object_wait_async(ph->handle, port->handle,
                                (uint64_t)(uintptr_t)ph,
                                ph->waitfor, ZX_WAIT_ASYNC_ONCE);
}

zx_status_t port_cancel(port_t* port, port_handler_t* ph) {
    zx_status_t r = zx_port_cancel(port->handle, ph->handle,
                                   (uint64_t)(uintptr_t)ph);
    zprintf("port_cancel(%p, %p) obj=%x port=%x: r = %d\n",
            port, ph, ph->handle, port->handle, r);
    return r;
}

zx_status_t port_queue(port_t* port, port_handler_t* ph, uint32_t evt) {
    zx_port_packet_t pkt;
    pkt.key = (uintptr_t)ph;
    pkt.user.u32[0] = evt;
    zx_status_t r = zx_port_queue(port->handle, &pkt);
    zprintf("port_queue(%p, %p) obj=%x port=%x evt=%x: r=%d\n",
            port, ph, ph->handle, port->handle, r, evt);
    return r;
}

zx_status_t port_dispatch(port_t* port, zx_time_t deadline, bool once) {
    for (;;) {
        zx_port_packet_t pkt;
        zx_status_t r;
        if ((r = zx_port_wait(port->handle, deadline, &pkt)) != ZX_OK) {
            if (r != ZX_ERR_TIMED_OUT) {
                printf("port_dispatch: port wait failed %d\n", r);
            }
            return r;
        }
        port_handler_t* ph = (void*) (uintptr_t) pkt.key;
        if (pkt.type == ZX_PKT_TYPE_USER) {
            zprintf("port_dispatch(%p) port=%x ph=%p func=%p: evt=%x\n",
                    port, port->handle, ph, ph->func, pkt.user.u32[0]);
            ph->func(ph, 0, pkt.user.u32[0]);
        } else {
            zprintf("port_dispatch(%p) port=%x ph=%p func=%p: signals=%x\n",
                    port, port->handle, ph, ph->func, pkt.signal.observed);
            if (ph->func(ph, pkt.signal.observed, 0) == ZX_OK) {
                port_wait(port, ph);
            }
        }
        if (once) {
            return ZX_OK;
        }
    }
}

static zx_status_t port_fd_handler_func(port_handler_t* ph, zx_signals_t signals, uint32_t evt) {
    port_fd_handler_t* fh = (void*) ph;

    if (evt) {
        return fh->func(fh, 0, evt);
    } else {
        uint32_t pollevt;
        fdio_unsafe_wait_end(fh->fdio_context, signals, &pollevt);
        return fh->func(fh, pollevt, 0);
    }
}

zx_status_t port_fd_handler_init(port_fd_handler_t* fh, int fd, unsigned pollevt) {
    fdio_t* io = fdio_unsafe_fd_to_io(fd);
    if (io == NULL) {
        return ZX_ERR_INVALID_ARGS;
    }
    fdio_unsafe_wait_begin(io, pollevt, &fh->ph.handle, &fh->ph.waitfor);
    fh->ph.func = port_fd_handler_func;
    fh->fdio_context = io;
    return ZX_OK;
}

void port_fd_handler_done(port_fd_handler_t* fh) {
    fdio_unsafe_release(fh->fdio_context);
    fh->fdio_context = NULL;
    fh->ph.handle = ZX_HANDLE_INVALID;
    fh->ph.waitfor = 0;
}
