/*
 * 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 "qapi/error.h"
#include "qemu/cutils.h"
#include "qemu/option.h"
#include "ivshmem-server.h"

#define IVSHMEM_SERVER_DEFAULT_VERBOSE        0
#define IVSHMEM_SERVER_DEFAULT_FOREGROUND     0
#define IVSHMEM_SERVER_DEFAULT_PID_FILE       "/var/run/ivshmem-server.pid"
#define IVSHMEM_SERVER_DEFAULT_UNIX_SOCK_PATH "/tmp/ivshmem_socket"
#define IVSHMEM_SERVER_DEFAULT_SHM_PATH       "ivshmem"
#define IVSHMEM_SERVER_DEFAULT_SHM_SIZE       (4 * 1024 * 1024)
#define IVSHMEM_SERVER_DEFAULT_N_VECTORS      1

/* used to quit on signal SIGTERM */
static int ivshmem_server_quit;

/* arguments given by the user */
typedef struct IvshmemServerArgs {
    bool verbose;
    bool foreground;
    const char *pid_file;
    const char *unix_socket_path;
    const char *shm_path;
    bool use_shm_open;
    uint64_t shm_size;
    unsigned n_vectors;
} IvshmemServerArgs;

static void
ivshmem_server_usage(const char *progname)
{
    printf("Usage: %s [OPTION]...\n"
           "  -h: show this help\n"
           "  -v: verbose mode\n"
           "  -F: foreground mode (default is to daemonize)\n"
           "  -p <pid-file>: path to the PID file (used in daemon mode only)\n"
           "     default " IVSHMEM_SERVER_DEFAULT_PID_FILE "\n"
           "  -S <unix-socket-path>: path to the unix socket to listen to\n"
           "     default " IVSHMEM_SERVER_DEFAULT_UNIX_SOCK_PATH "\n"
           "  -M <shm-name>: POSIX shared memory object to use\n"
           "     default " IVSHMEM_SERVER_DEFAULT_SHM_PATH "\n"
           "  -m <dir-name>: where to create shared memory\n"
           "  -l <size>: size of shared memory in bytes\n"
           "     suffixes K, M and G can be used, e.g. 1K means 1024\n"
           "     default %u\n"
           "  -n <nvectors>: number of vectors\n"
           "     default %u\n",
           progname, IVSHMEM_SERVER_DEFAULT_SHM_SIZE,
           IVSHMEM_SERVER_DEFAULT_N_VECTORS);
}

static void
ivshmem_server_help(const char *progname)
{
    fprintf(stderr, "Try '%s -h' for more information.\n", progname);
}

/* parse the program arguments, exit on error */
static void
ivshmem_server_parse_args(IvshmemServerArgs *args, int argc, char *argv[])
{
    int c;
    unsigned long long v;
    Error *err = NULL;

    while ((c = getopt(argc, argv, "hvFp:S:m:M:l:n:")) != -1) {

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

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

        case 'F': /* foreground */
            args->foreground = 1;
            break;

        case 'p': /* pid file */
            args->pid_file = optarg;
            break;

        case 'S': /* unix socket path */
            args->unix_socket_path = optarg;
            break;

        case 'M': /* shm name */
        case 'm': /* dir name */
            args->shm_path = optarg;
            args->use_shm_open = c == 'M';
            break;

        case 'l': /* shm size */
            if (!parse_option_size("shm_size", optarg, &args->shm_size,
                                   &err)) {
                error_report_err(err);
                ivshmem_server_help(argv[0]);
                exit(1);
            }
            break;

        case 'n': /* number of vectors */
            if (parse_uint_full(optarg, &v, 0) < 0) {
                fprintf(stderr, "cannot parse n_vectors\n");
                ivshmem_server_help(argv[0]);
                exit(1);
            }
            args->n_vectors = v;
            break;

        default:
            ivshmem_server_usage(argv[0]);
            exit(1);
            break;
        }
    }

    if (args->n_vectors > IVSHMEM_SERVER_MAX_VECTORS) {
        fprintf(stderr, "too many requested vectors (max is %d)\n",
                IVSHMEM_SERVER_MAX_VECTORS);
        ivshmem_server_help(argv[0]);
        exit(1);
    }

    if (args->verbose == 1 && args->foreground == 0) {
        fprintf(stderr, "cannot use verbose in daemon mode\n");
        ivshmem_server_help(argv[0]);
        exit(1);
    }
}

/* wait for events on listening server unix socket and connected client
 * sockets */
static int
ivshmem_server_poll_events(IvshmemServer *server)
{
    fd_set fds;
    int ret = 0, maxfd;

    while (!ivshmem_server_quit) {

        FD_ZERO(&fds);
        maxfd = 0;
        ivshmem_server_get_fds(server, &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 (ivshmem_server_handle_fds(server, &fds, maxfd) < 0) {
            fprintf(stderr, "ivshmem_server_handle_fds() failed\n");
            break;
        }
    }

    return ret;
}

static void
ivshmem_server_quit_cb(int signum)
{
    ivshmem_server_quit = 1;
}

int
main(int argc, char *argv[])
{
    IvshmemServer server;
    struct sigaction sa, sa_quit;
    IvshmemServerArgs args = {
        .verbose = IVSHMEM_SERVER_DEFAULT_VERBOSE,
        .foreground = IVSHMEM_SERVER_DEFAULT_FOREGROUND,
        .pid_file = IVSHMEM_SERVER_DEFAULT_PID_FILE,
        .unix_socket_path = IVSHMEM_SERVER_DEFAULT_UNIX_SOCK_PATH,
        .shm_path = IVSHMEM_SERVER_DEFAULT_SHM_PATH,
        .use_shm_open = true,
        .shm_size = IVSHMEM_SERVER_DEFAULT_SHM_SIZE,
        .n_vectors = IVSHMEM_SERVER_DEFAULT_N_VECTORS,
    };
    int ret = 1;

    /*
     * Do not remove this notice without adding proper error handling!
     * Start with handling ivshmem_server_send_one_msg() failure.
     */
    printf("*** Example code, do not use in production ***\n");

    /* parse arguments, will exit on error */
    ivshmem_server_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");
        goto err;
    }

    sa_quit.sa_handler = ivshmem_server_quit_cb;
    sa_quit.sa_flags = 0;
    if (sigemptyset(&sa_quit.sa_mask) == -1 ||
        sigaction(SIGTERM, &sa_quit, 0) == -1 ||
        sigaction(SIGINT, &sa_quit, 0) == -1) {
        perror("failed to add signal handler; sigaction");
        goto err;
    }

    /* init the ivshms structure */
    if (ivshmem_server_init(&server, args.unix_socket_path,
                            args.shm_path, args.use_shm_open,
                            args.shm_size, args.n_vectors, args.verbose) < 0) {
        fprintf(stderr, "cannot init server\n");
        goto err;
    }

    /* start the ivshmem server (open shm & unix socket) */
    if (ivshmem_server_start(&server) < 0) {
        fprintf(stderr, "cannot bind\n");
        goto err;
    }

    /* daemonize if asked to */
    if (!args.foreground) {
        FILE *fp;

        if (qemu_daemon(1, 1) < 0) {
            fprintf(stderr, "cannot daemonize: %s\n", strerror(errno));
            goto err_close;
        }

        /* write pid file */
        fp = fopen(args.pid_file, "w");
        if (fp == NULL) {
            fprintf(stderr, "cannot write pid file: %s\n", strerror(errno));
            goto err_close;
        }

        fprintf(fp, "%d\n", (int) getpid());
        fclose(fp);
    }

    ivshmem_server_poll_events(&server);
    fprintf(stdout, "server disconnected\n");
    ret = 0;

err_close:
    ivshmem_server_close(&server);
err:
    return ret;
}
