/*
 * 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-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=%ld vector=%d\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;
}
