// 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 <threads.h>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <fuchsia/hardware/pty/c/fidl.h>
#include <zircon/status.h>

#include "pty-core.h"
#include "pty-fifo.h"

typedef struct pty_server_dev {
    pty_server_t srv;

    mtx_t lock;
    pty_fifo_t fifo;
} pty_server_dev_t;

static zx_device_t* pty_root;

static zx_status_t psd_recv(pty_server_t* ps, const void* data, size_t len, size_t* actual) {
    if (len == 0) {
        *actual = 0;
        return ZX_OK;
    }

    pty_server_dev_t* psd = static_cast<pty_server_dev_t*>(containerof(ps, pty_server_dev_t, srv));
    zxlogf(TRACE, "PTY Server Device %p recv\n", ps);

    bool was_empty = pty_fifo_is_empty(&psd->fifo);
    *actual = pty_fifo_write(&psd->fifo, data, len, false);
    if (was_empty && *actual) {
        device_state_set(ps->zxdev, DEV_STATE_READABLE);
    }

    if (*actual == 0) {
        return ZX_ERR_SHOULD_WAIT;
    } else {
        return ZX_OK;
    }
}

static zx_status_t psd_read(void* ctx, void* buf, size_t count, zx_off_t off, size_t* actual) {
    auto psd = static_cast<pty_server_dev_t*>(ctx);
    zxlogf(TRACE, "PTY Server Device %p read\n", psd);

    bool eof = false;

    mtx_lock(&psd->srv.lock);
    bool was_full = pty_fifo_is_full(&psd->fifo);
    size_t length = pty_fifo_read(&psd->fifo, buf, count);
    if (pty_fifo_is_empty(&psd->fifo)) {
        if (list_is_empty(&psd->srv.clients)) {
            eof = true;
        } else {
            device_state_clr(psd->srv.zxdev, DEV_STATE_READABLE);
        }
    }
    if (was_full && length) {
        pty_server_resume_locked(&psd->srv);
    }
    mtx_unlock(&psd->srv.lock);

    if (length > 0) {
        *actual = length;
        return ZX_OK;
    } else if (eof) {
        *actual = 0;
        return ZX_OK;
    } else {
        return ZX_ERR_SHOULD_WAIT;
    }
}

static zx_status_t psd_write(void* ctx, const void* buf, size_t count, zx_off_t off,
                             size_t* actual) {
    auto psd = static_cast<pty_server_dev_t*>(ctx);
    zxlogf(TRACE, "PTY Server Device %p write\n", psd);
    size_t length;
    zx_status_t status;

    if ((status = pty_server_send(&psd->srv, buf, count, false, &length)) < 0) {
        return status;
    } else {
        *actual = length;
        return ZX_OK;
    }
}

zx_status_t psd_ClrSetFeature(void* ctx, uint32_t clr, uint32_t set, fidl_txn_t* txn) {
    return fuchsia_hardware_pty_DeviceClrSetFeature_reply(txn, ZX_ERR_NOT_SUPPORTED, 0);
}

zx_status_t psd_GetWindowSize(void* ctx, fidl_txn_t* txn) {
    fuchsia_hardware_pty_WindowSize wsz = {
        .width = 0,
        .height = 0
    };
    return fuchsia_hardware_pty_DeviceGetWindowSize_reply(txn, ZX_ERR_NOT_SUPPORTED, &wsz);
}

zx_status_t psd_MakeActive(void* ctx, uint32_t client_pty_id, fidl_txn_t* txn) {
    return fuchsia_hardware_pty_DeviceMakeActive_reply(txn, ZX_ERR_NOT_SUPPORTED);
}

zx_status_t psd_ReadEvents(void* ctx, fidl_txn_t* txn) {
    return fuchsia_hardware_pty_DeviceReadEvents_reply(txn, ZX_ERR_NOT_SUPPORTED, 0);
}

zx_status_t psd_SetWindowSize(void* ctx, const fuchsia_hardware_pty_WindowSize* size,
                              fidl_txn_t* txn) {
    auto psd = static_cast<pty_server_dev_t*>(ctx);
    zxlogf(TRACE, "PTY Server Device %p message: set window size\n", psd);
    pty_server_set_window_size(&psd->srv, size->width, size->height);
    return fuchsia_hardware_pty_DeviceSetWindowSize_reply(txn, ZX_OK);
}


static fuchsia_hardware_pty_Device_ops_t psd_fidl_ops = {
    .OpenClient = pty_server_fidl_OpenClient,
    .ClrSetFeature = psd_ClrSetFeature,
    .GetWindowSize = psd_GetWindowSize,
    .MakeActive = psd_MakeActive,
    .ReadEvents = psd_ReadEvents,
    .SetWindowSize = psd_SetWindowSize
};

zx_status_t psd_message(void* ctx, fidl_msg_t* msg, fidl_txn_t* txn) {
    return fuchsia_hardware_pty_Device_dispatch(ctx, txn, msg, &psd_fidl_ops);
}

// Since we have no special functionality,
// we just use the implementations from pty-core
// directly.
static zx_protocol_device_t psd_ops = []() {
    zx_protocol_device_t ops = {};
    ops.version = DEVICE_OPS_VERSION;
    // ops.open = default, allow cloning;
    ops.release = pty_server_release;
    ops.read = psd_read;
    ops.write = psd_write;
    ops.message = psd_message;
    return ops;
}();

// ptmx device - used to obtain the pty server of a new pty instance

static zx_status_t ptmx_open(void* ctx, zx_device_t** out, uint32_t flags) {
    zxlogf(TRACE, "PTMX open\n");
    auto psd = static_cast<pty_server_dev_t*>(calloc(1, sizeof(pty_server_dev_t)));
    if (!psd) {
        zxlogf(ERROR, "No memory for pty server device\n");
        return ZX_ERR_NO_MEMORY;
    }

    pty_server_init(&psd->srv);
    psd->srv.recv = psd_recv;
    psd->srv.set_window_size = psd_SetWindowSize;
    mtx_init(&psd->lock, mtx_plain);
    psd->fifo.head = 0;
    psd->fifo.tail = 0;

    device_add_args_t args = {};
    args.version = DEVICE_ADD_ARGS_VERSION;
    args.name = "pty";
    args.ctx = psd;
    args.ops = &psd_ops;
    args.proto_id = ZX_PROTOCOL_PTY;
    args.flags = DEVICE_ADD_INSTANCE;

    zx_status_t status = device_add(pty_root, &args, &psd->srv.zxdev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "Failed to add PTMX device: %s\n", zx_status_get_string(status));
        free(psd);
        return status;
    }

    *out = psd->srv.zxdev;
    return ZX_OK;
}

static zx_protocol_device_t ptmx_ops = []() {
    zx_protocol_device_t ops = {};
    ops.version = DEVICE_OPS_VERSION;
    ops.open = ptmx_open;
    return ops;
}();

static zx_status_t ptmx_bind(void* ctx, zx_device_t* parent) {
    zxlogf(TRACE, "PTMX bind\n");
    device_add_args_t args = {};
    args.version = DEVICE_ADD_ARGS_VERSION;
    args.name = "ptmx";
    args.ops = &ptmx_ops;

    zx_status_t status = device_add(parent, &args, &pty_root);
    if (status != ZX_OK) {
        zxlogf(ERROR, "Failed to bind PTMX device: %s\n", zx_status_get_string(status));
    }

    return status;
}

static zx_driver_ops_t ptmx_driver_ops = []() {
    zx_driver_ops_t ops = {};
    ops.version = DRIVER_OPS_VERSION;
    ops.bind = ptmx_bind;
    return ops;
}();

// clang-format off
ZIRCON_DRIVER_BEGIN(ptmx, ptmx_driver_ops, "zircon", "0.1", 1)
    BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_MISC_PARENT),
ZIRCON_DRIVER_END(ptmx)
