/*
 * Copyright (C) 2020, Matthias Weckbecker <matthias@weckbecker.name>
 *
 * License: GNU GPL, version 2 or later.
 *   See the COPYING file in the top-level directory.
 */
#include <inttypes.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <glib.h>

#include <qemu-plugin.h>

QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;

typedef struct {
    int64_t num;
    int64_t calls;
    int64_t errors;
} SyscallStats;

struct SyscallInfo {
    const char *name;
    int64_t write_sysno;
};

static const struct SyscallInfo arch_syscall_info[] = {
    { "aarch64", 64 },
    { "aarch64_be", 64 },
    { "alpha", 4 },
    { "arm", 4 },
    { "armeb", 4 },
    { "avr", -1 },
    { "hexagon", 64 },
    { "hppa", -1 },
    { "i386", 4 },
    { "loongarch64", -1 },
    { "m68k", 4 },
    { "microblaze", 4 },
    { "microblazeel", 4 },
    { "mips", 1 },
    { "mips64", 1 },
    { "mips64el", 1 },
    { "mipsel", 1 },
    { "mipsn32", 1 },
    { "mipsn32el", 1 },
    { "or1k", -1 },
    { "ppc", 4 },
    { "ppc64", 4 },
    { "ppc64le", 4 },
    { "riscv32", 64 },
    { "riscv64", 64 },
    { "rx", -1 },
    { "s390x", -1 },
    { "sh4", -1 },
    { "sh4eb", -1 },
    { "sparc", 4 },
    { "sparc32plus", 4 },
    { "sparc64", 4 },
    { "tricore", -1 },
    { "x86_64", 1 },
    { "xtensa", 13 },
    { "xtensaeb", 13 },
    { NULL, -1 },
};

static GMutex lock;
static GHashTable *statistics;
static GByteArray *memory_buffer;
static bool do_log_writes;
static int64_t write_sysno = -1;

static SyscallStats *get_or_create_entry(int64_t num)
{
    SyscallStats *entry =
        (SyscallStats *) g_hash_table_lookup(statistics, GINT_TO_POINTER(num));

    if (!entry) {
        entry = g_new0(SyscallStats, 1);
        entry->num = num;
        g_hash_table_insert(statistics, GINT_TO_POINTER(num), (gpointer) entry);
    }

    return entry;
}

/*
 * Hex-dump a GByteArray to the QEMU plugin output in the format:
 * 61 63 63 65 6c 09 09 20 20 20 66 70 75 09 09 09  | accel.....fpu...
 * 20 6d 6f 64 75 6c 65 2d 63 6f 6d 6d 6f 6e 2e 63  | .module-common.c
 */
static void hexdump(const GByteArray *data)
{
    g_autoptr(GString) out = g_string_new("");

    for (guint index = 0; index < data->len; index += 16) {
        for (guint col = 0; col < 16; col++) {
            if (index + col < data->len) {
                g_string_append_printf(out, "%02x ", data->data[index + col]);
            } else {
                g_string_append(out, "   ");
            }
        }

        g_string_append(out, " | ");

        for (guint col = 0; col < 16; col++) {
            if (index + col >= data->len) {
                break;
            }

            if (g_ascii_isgraph(data->data[index + col])) {
                g_string_append_printf(out, "%c", data->data[index + col]);
            } else {
                g_string_append(out, ".");
            }
        }

        g_string_append(out, "\n");
    }

    qemu_plugin_outs(out->str);
}

static void vcpu_syscall(qemu_plugin_id_t id, unsigned int vcpu_index,
                         int64_t num, uint64_t a1, uint64_t a2,
                         uint64_t a3, uint64_t a4, uint64_t a5,
                         uint64_t a6, uint64_t a7, uint64_t a8)
{
    if (statistics) {
        SyscallStats *entry;
        g_mutex_lock(&lock);
        entry = get_or_create_entry(num);
        entry->calls++;
        g_mutex_unlock(&lock);
    } else {
        g_autofree gchar *out = g_strdup_printf("syscall #%" PRIi64 "\n", num);
        qemu_plugin_outs(out);
    }

    if (do_log_writes && num == write_sysno) {
        if (qemu_plugin_read_memory_vaddr(a2, memory_buffer, a3)) {
            hexdump(memory_buffer);
        } else {
            fprintf(stderr, "Error reading memory from vaddr %"PRIu64"\n", a2);
        }
    }
}

static void vcpu_syscall_ret(qemu_plugin_id_t id, unsigned int vcpu_idx,
                             int64_t num, int64_t ret)
{
    if (statistics) {
        SyscallStats *entry;

        g_mutex_lock(&lock);
        /* Should always return an existent entry. */
        entry = get_or_create_entry(num);
        if (ret < 0) {
            entry->errors++;
        }
        g_mutex_unlock(&lock);
    } else {
        g_autofree gchar *out = g_strdup_printf(
             "syscall #%" PRIi64 " returned -> %" PRIi64 "\n", num, ret);
        qemu_plugin_outs(out);
    }
}

static void print_entry(gpointer val, gpointer user_data)
{
    SyscallStats *entry = (SyscallStats *) val;
    int64_t syscall_num = entry->num;
    g_autofree gchar *out = g_strdup_printf(
        "%-13" PRIi64 "%-6" PRIi64 " %" PRIi64 "\n",
        syscall_num, entry->calls, entry->errors);
    qemu_plugin_outs(out);
}

static gint comp_func(gconstpointer ea, gconstpointer eb)
{
    SyscallStats *ent_a = (SyscallStats *) ea;
    SyscallStats *ent_b = (SyscallStats *) eb;

    return ent_a->calls > ent_b->calls ? -1 : 1;
}

/* ************************************************************************* */
static void plugin_exit(qemu_plugin_id_t id, void *p)
{
    if (!statistics) {
        return;
    }

    g_mutex_lock(&lock);
    GList *entries = g_hash_table_get_values(statistics);
    entries = g_list_sort(entries, comp_func);
    qemu_plugin_outs("syscall no.  calls  errors\n");

    g_list_foreach(entries, print_entry, NULL);

    g_list_free(entries);
    g_hash_table_destroy(statistics);
    g_mutex_unlock(&lock);
}

QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
                                           const qemu_info_t *info,
                                           int argc, char **argv)
{
    bool do_print = false;

    for (int i = 0; i < argc; i++) {
        char *opt = argv[i];
        g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);

        if (g_strcmp0(tokens[0], "print") == 0) {
            if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_print)) {
                fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
            }
        } else if (g_strcmp0(tokens[0], "log_writes") == 0) {
            if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_log_writes)) {
                fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
            }
        } else {
            fprintf(stderr, "unsupported argument: %s\n", argv[i]);
            return -1;
        }
    }

    if (!do_print) {
        statistics = g_hash_table_new_full(NULL, g_direct_equal, NULL, g_free);
    }

    if (do_log_writes) {
        for (const struct SyscallInfo *syscall_info = arch_syscall_info;
            syscall_info->name != NULL; syscall_info++) {

            if (g_strcmp0(syscall_info->name, info->target_name) == 0) {
                write_sysno = syscall_info->write_sysno;
                break;
            }
        }

        if (write_sysno == -1) {
            fprintf(stderr, "write syscall number not found\n");
            return -1;
        }

        memory_buffer = g_byte_array_new();
    }

    qemu_plugin_register_vcpu_syscall_cb(id, vcpu_syscall);
    qemu_plugin_register_vcpu_syscall_ret_cb(id, vcpu_syscall_ret);
    qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
    return 0;
}
