/*
 * Copyright 6WIND S.A., 2014
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * (at your option) any later version.  See the COPYING file in the
 * top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu-common.h"

#include "ivshmem-client.h"

#define IVSHMEM_CLIENT_DEFAULT_VERBOSE        0
#define IVSHMEM_CLIENT_DEFAULT_UNIX_SOCK_PATH "/tmp/ivshmem_socket"

typedef struct IvshmemClientArgs {
    bool verbose;
    const char *unix_sock_path;
} IvshmemClientArgs;

/* show ivshmem_client_usage and exit with given error code */
static void
ivshmem_client_usage(const char *name, int code)
{
    fprintf(stderr, "%s [opts]\n", name);
    fprintf(stderr, "  -h: show this help\n");
    fprintf(stderr, "  -v: verbose mode\n");
    fprintf(stderr, "  -S <unix_sock_path>: path to the unix socket\n"
                    "     to connect to.\n"
                    "     default=%s\n", IVSHMEM_CLIENT_DEFAULT_UNIX_SOCK_PATH);
    exit(code);
}

/* parse the program arguments, exit on error */
static void
ivshmem_client_parse_args(IvshmemClientArgs *args, int argc, char *argv[])
{
    int c;

    while ((c = getopt(argc, argv,
                       "h"  /* help */
                       "v"  /* verbose */
                       "S:" /* unix_sock_path */
                      )) != -1) {

        switch (c) {
        case 'h': /* help */
            ivshmem_client_usage(argv[0], 0);
            break;

        case 'v': /* verbose */
            args->verbose = 1;
            break;

        case 'S': /* unix_sock_path */
            args->unix_sock_path = optarg;
            break;

        default:
            ivshmem_client_usage(argv[0], 1);
            break;
        }
    }
}

/* show command line help */
static void
ivshmem_client_cmdline_help(void)
{
    printf("dump: dump peers (including us)\n"
           "int <peer> <vector>: notify one vector on a peer\n"
           "int <peer> all: notify all vectors of a peer\n"
           "int all: notify all vectors of all peers (excepting us)\n");
}

/* read stdin and handle commands */
static int
ivshmem_client_handle_stdin_command(IvshmemClient *client)
{
    IvshmemClientPeer *peer;
    char buf[128];
    char *s, *token;
    int ret;
    int peer_id, vector;

    memset(buf, 0, sizeof(buf));
    ret = read(0, buf, sizeof(buf) - 1);
    if (ret < 0) {
        return -1;
    }

    s = buf;
    while ((token = strsep(&s, "\n\r;")) != NULL) {
        if (!strcmp(token, "")) {
            continue;
        }
        if (!strcmp(token, "?")) {
            ivshmem_client_cmdline_help();
        }
        if (!strcmp(token, "help")) {
            ivshmem_client_cmdline_help();
        } else if (!strcmp(token, "dump")) {
            ivshmem_client_dump(client);
        } else if (!strcmp(token, "int all")) {
            ivshmem_client_notify_broadcast(client);
        } else if (sscanf(token, "int %d %d", &peer_id, &vector) == 2) {
            peer = ivshmem_client_search_peer(client, peer_id);
            if (peer == NULL) {
                printf("cannot find peer_id = %d\n", peer_id);
                continue;
            }
            ivshmem_client_notify(client, peer, vector);
        } else if (sscanf(token, "int %d all", &peer_id) == 1) {
            peer = ivshmem_client_search_peer(client, peer_id);
            if (peer == NULL) {
                printf("cannot find peer_id = %d\n", peer_id);
                continue;
            }
            ivshmem_client_notify_all_vects(client, peer);
        } else {
            printf("invalid command, type help\n");
        }
    }

    printf("cmd> ");
    fflush(stdout);
    return 0;
}

/* listen on stdin (command line), on unix socket (notifications of new
 * and dead peers), and on eventfd (IRQ request) */
static int
ivshmem_client_poll_events(IvshmemClient *client)
{
    fd_set fds;
    int ret, maxfd;

    while (1) {

        FD_ZERO(&fds);
        FD_SET(0, &fds); /* add stdin in fd_set */
        maxfd = 1;

        ivshmem_client_get_fds(client, &fds, &maxfd);

        ret = select(maxfd, &fds, NULL, NULL, NULL);
        if (ret < 0) {
            if (errno == EINTR) {
                continue;
            }

            fprintf(stderr, "select error: %s\n", strerror(errno));
            break;
        }
        if (ret == 0) {
            continue;
        }

        if (FD_ISSET(0, &fds) &&
            ivshmem_client_handle_stdin_command(client) < 0 && errno != EINTR) {
            fprintf(stderr, "ivshmem_client_handle_stdin_command() failed\n");
            break;
        }

        if (ivshmem_client_handle_fds(client, &fds, maxfd) < 0) {
            fprintf(stderr, "ivshmem_client_handle_fds() failed\n");
            break;
        }
    }

    return ret;
}

/* callback when we receive a notification (just display it) */
static void
ivshmem_client_notification_cb(const IvshmemClient *client,
                               const IvshmemClientPeer *peer,
                               unsigned vect, void *arg)
{
    (void)client;
    (void)arg;
    printf("receive notification from peer_id=%" PRId64 " vector=%u\n",
           peer->id, vect);
}

int
main(int argc, char *argv[])
{
    struct sigaction sa;
    IvshmemClient client;
    IvshmemClientArgs args = {
        .verbose = IVSHMEM_CLIENT_DEFAULT_VERBOSE,
        .unix_sock_path = IVSHMEM_CLIENT_DEFAULT_UNIX_SOCK_PATH,
    };

    /* parse arguments, will exit on error */
    ivshmem_client_parse_args(&args, argc, argv);

    /* Ignore SIGPIPE, see this link for more info:
     * http://www.mail-archive.com/libevent-users@monkey.org/msg01606.html */
    sa.sa_handler = SIG_IGN;
    sa.sa_flags = 0;
    if (sigemptyset(&sa.sa_mask) == -1 ||
        sigaction(SIGPIPE, &sa, 0) == -1) {
        perror("failed to ignore SIGPIPE; sigaction");
        return 1;
    }

    ivshmem_client_cmdline_help();
    printf("cmd> ");
    fflush(stdout);

    if (ivshmem_client_init(&client, args.unix_sock_path,
                            ivshmem_client_notification_cb, NULL,
                            args.verbose) < 0) {
        fprintf(stderr, "cannot init client\n");
        return 1;
    }

    while (1) {
        if (ivshmem_client_connect(&client) < 0) {
            fprintf(stderr, "cannot connect to server, retry in 1 second\n");
            sleep(1);
            continue;
        }

        fprintf(stdout, "listen on server socket %d\n", client.sock_fd);

        if (ivshmem_client_poll_events(&client) == 0) {
            continue;
        }

        /* disconnected from server, reset all peers */
        fprintf(stdout, "disconnected from server\n");

        ivshmem_client_close(&client);
    }

    return 0;
}
