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

#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <unistd.h>

#include <fdio/io.h>

#include <zircon/device/pty.h>

// returns an int to avoid sign errors from ASSERT_*()
static int fd_signals(int fd) {
    uint32_t signals = 0;
    fdio_wait_fd(fd, 0, &signals, 0);
    return signals;
}

static int write_full(int fd) {
    char tmp[300];
    memset(tmp, 0x33, sizeof(tmp));
    int total = 0;
    for (;;) {
        int r = write(fd, tmp, sizeof(tmp));
        if (r < 0) {
            if (errno == EAGAIN) {
                break;
            }
            return -errno;
        }
        if (r == 0) {
            break;
        }
        total += r;
    }
    return total;
}

static int read_all(int fd) {
    char tmp[700];
    int total = 0;
    for (;;) {
        int r = read(fd, tmp, sizeof(tmp));
        if (r < 0) {
            if (errno == EAGAIN) {
                break;
            }
            return -errno;
        }
        if (r == 0) {
            break;
        }
        for (int n = 0; n < r; n++) {
            if (tmp[n] != 0x33) {
                return -EFAULT;
            }
        }
        total += r;
    }
    return total;
}

static bool pty_test(void) {
    BEGIN_TEST;

    int ps = open("/dev/misc/ptmx", O_RDWR | O_NONBLOCK);
    ASSERT_GE(ps, 0, "");

    int pc = openat(ps, "0", O_RDWR | O_NONBLOCK);
    ASSERT_GE(pc, 0, "");

    char tmp[32];

    ASSERT_EQ(fd_signals(ps), POLLOUT, "");
    ASSERT_EQ(fd_signals(pc), POLLOUT, "");

    // nothing to read
    ASSERT_EQ(read(ps, tmp, 32), -1, "");
    ASSERT_EQ(errno, EAGAIN, "");
    ASSERT_EQ(read(pc, tmp, 32), -1, "");
    ASSERT_EQ(errno, EAGAIN, "");

    // write server, read client
    ASSERT_EQ(write(ps, "xyzzy", 5), 5, "");
    ASSERT_EQ(fd_signals(pc), POLLIN | POLLOUT, "");

    memset(tmp, 0xee, 5);
    ASSERT_EQ(read(pc, tmp, 5), 5, "");
    ASSERT_EQ(memcmp(tmp, "xyzzy", 5), 0, "");
    ASSERT_EQ(fd_signals(pc), POLLOUT, "");

    // write client, read server
    ASSERT_EQ(write(pc, "xyzzy", 5), 5, "");
    ASSERT_EQ(fd_signals(ps), POLLIN | POLLOUT, "");

    memset(tmp, 0xee, 5);
    ASSERT_EQ(read(ps, tmp, 5), 5, "");
    ASSERT_EQ(memcmp(tmp, "xyzzy", 5), 0, "");
    ASSERT_EQ(fd_signals(ps), POLLOUT, "");

    // write server until full, then drain
    ASSERT_EQ(write_full(ps), 4096, "");
    ASSERT_EQ(fd_signals(ps), 0, "");
    ASSERT_EQ(read_all(pc), 4096, "");
    ASSERT_EQ(fd_signals(ps), POLLOUT, "");

    // write client until full, then drain
    ASSERT_EQ(write_full(pc), 4096, "");
    ASSERT_EQ(fd_signals(pc), 0, "");
    ASSERT_EQ(read_all(ps), 4096, "");
    ASSERT_EQ(fd_signals(pc), POLLOUT, "");

    // verify no events pending
    uint32_t events;
    ASSERT_EQ(ioctl_pty_read_events(pc, &events), (ssize_t)sizeof(events), "");
    ASSERT_EQ(events, 0u, "");

    // write a ctrl-c
    ASSERT_EQ(write(ps, "\x03", 1), 1, "");

    // should be an event now
    ASSERT_EQ(ioctl_pty_read_events(pc, &events), (ssize_t)sizeof(events), "");
    ASSERT_EQ(events, PTY_EVENT_INTERRUPT, "");

    // should vanish once we read it
    ASSERT_EQ(ioctl_pty_read_events(pc, &events), (ssize_t)sizeof(events), "");
    ASSERT_EQ(events, 0u, "");

    // write something containing a special char
    // should write up to and including the special char
    // converting the special char to a signal
    ASSERT_EQ(write(ps, "hello\x03world", 11), 6, "");
    ASSERT_EQ(read(pc, tmp, 6), 5, "");
    ASSERT_EQ(memcmp(tmp, "hello", 5), 0, "");
    ASSERT_EQ(ioctl_pty_read_events(pc, &events), (ssize_t)sizeof(events), "");
    ASSERT_EQ(events, PTY_EVENT_INTERRUPT, "");


    pty_window_size_t ws;
    ASSERT_EQ(ioctl_pty_get_window_size(pc, &ws), (ssize_t)sizeof(ws), "");
    ASSERT_EQ(ws.width, 0u, "");
    ASSERT_EQ(ws.height, 0u, "");
    ws.width = 80;
    ws.height = 25;
    ASSERT_EQ(ioctl_pty_set_window_size(ps, &ws), 0, "");
    ASSERT_EQ(ioctl_pty_get_window_size(pc, &ws), (ssize_t)sizeof(ws), "");
    ASSERT_EQ(ws.width, 80u, "");
    ASSERT_EQ(ws.height, 25u, "");

    // verify that we don't get events for special chars in raw mode
    pty_clr_set_t cs = {
        .clr = 0,
        .set = PTY_FEATURE_RAW,
    };
    ASSERT_EQ(ioctl_pty_clr_set_feature(pc, &cs), 0, "");
    ASSERT_EQ(write(ps, "\x03", 1), 1, "");
    ASSERT_EQ(read(pc, tmp, 1), 1, "");
    ASSERT_EQ(tmp[0], '\x03', "");
    ASSERT_EQ(ioctl_pty_read_events(pc, &events), (ssize_t)sizeof(events), "");
    ASSERT_EQ(events, 0u, "");

    // create a second client
    int pc1 = openat(pc, "1", O_RDWR | O_NONBLOCK);
    ASSERT_GE(pc1, 0, "");

    // reads/writes to non-active client should block
    ASSERT_EQ(fd_signals(pc1), 0, "");
    ASSERT_EQ(write(pc1, "test", 4), -1, "");
    ASSERT_EQ(errno, EAGAIN, "");
    ASSERT_EQ(read(pc1, tmp, 4), -1, "");
    ASSERT_EQ(errno, EAGAIN, "");

    uint32_t n = 2;
    ASSERT_EQ(ioctl_pty_make_active(pc, &n), ZX_ERR_NOT_FOUND, "");

    // non-controlling client cannot change active client
    ASSERT_EQ(ioctl_pty_make_active(pc1, &n), ZX_ERR_ACCESS_DENIED, "");

    // but controlling client can
    n = 1;
    ASSERT_EQ(ioctl_pty_make_active(pc, &n), ZX_OK, "");
    ASSERT_EQ(fd_signals(pc), 0, "");
    ASSERT_EQ(fd_signals(pc1), POLLOUT, "");
    ASSERT_EQ(write(pc1, "test", 4), 4, "");
    ASSERT_EQ(read(ps, tmp, 4), 4, "");
    ASSERT_EQ(memcmp(tmp, "test", 4), 0, "");

    // make sure controlling client observes departing active client
    close(pc1);
    ASSERT_EQ(fd_signals(pc), POLLHUP | POLLPRI, "");
    ASSERT_EQ(ioctl_pty_read_events(pc, &events), (ssize_t)sizeof(events), "");
    ASSERT_EQ(events, PTY_EVENT_HANGUP, "");

    // verify that server observes depature of last client
    close(pc);
    ASSERT_EQ(fd_signals(ps), POLLHUP | POLLIN, "");

    close(ps);

    END_TEST;
}

BEGIN_TEST_CASE(pty_tests)
RUN_TEST(pty_test)
END_TEST_CASE(pty_tests)

int main(int argc, char** argv) {
    return unittest_run_all_tests(argc, argv) ? 0 : -1;
}
