// 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_wait_repeating(port_t* port, port_handler_t* ph) {
    zprintf("port_wait_repeating(%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_REPEATING);
}


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