/*
 * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
 *
 * 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 {
    GMutex lock;
    int index;
    uint64_t bb_count;
    uint64_t insn_count;
} CPUCount;

/* Used by the inline & linux-user counts */
static bool do_inline;
static CPUCount inline_count;

/* Dump running CPU total on idle? */
static bool idle_report;
static GPtrArray *counts;
static int max_cpus;

static void gen_one_cpu_report(CPUCount *count, GString *report)
{
    if (count->bb_count) {
        g_string_append_printf(report, "CPU%d: "
                               "bb's: %" PRIu64", insns: %" PRIu64 "\n",
                               count->index,
                               count->bb_count, count->insn_count);
    }
}

static void plugin_exit(qemu_plugin_id_t id, void *p)
{
    g_autoptr(GString) report = g_string_new("");

    if (do_inline || !max_cpus) {
        g_string_printf(report, "bb's: %" PRIu64", insns: %" PRIu64 "\n",
                        inline_count.bb_count, inline_count.insn_count);
    } else {
        g_ptr_array_foreach(counts, (GFunc) gen_one_cpu_report, report);
    }
    qemu_plugin_outs(report->str);
}

static void vcpu_idle(qemu_plugin_id_t id, unsigned int cpu_index)
{
    CPUCount *count = g_ptr_array_index(counts, cpu_index);
    g_autoptr(GString) report = g_string_new("");
    gen_one_cpu_report(count, report);

    if (report->len > 0) {
        g_string_prepend(report, "Idling ");
        qemu_plugin_outs(report->str);
    }
}

static void vcpu_tb_exec(unsigned int cpu_index, void *udata)
{
    CPUCount *count = max_cpus ?
        g_ptr_array_index(counts, cpu_index) : &inline_count;

    uintptr_t n_insns = (uintptr_t)udata;
    g_mutex_lock(&count->lock);
    count->insn_count += n_insns;
    count->bb_count++;
    g_mutex_unlock(&count->lock);
}

static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
{
    size_t n_insns = qemu_plugin_tb_n_insns(tb);

    if (do_inline) {
        qemu_plugin_register_vcpu_tb_exec_inline(tb, QEMU_PLUGIN_INLINE_ADD_U64,
                                                 &inline_count.bb_count, 1);
        qemu_plugin_register_vcpu_tb_exec_inline(tb, QEMU_PLUGIN_INLINE_ADD_U64,
                                                 &inline_count.insn_count,
                                                 n_insns);
    } else {
        qemu_plugin_register_vcpu_tb_exec_cb(tb, vcpu_tb_exec,
                                             QEMU_PLUGIN_CB_NO_REGS,
                                             (void *)n_insns);
    }
}

QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
                                           const qemu_info_t *info,
                                           int argc, char **argv)
{
    int i;

    for (i = 0; i < argc; i++) {
        char *opt = argv[i];
        g_autofree char **tokens = g_strsplit(opt, "=", 2);
        if (g_strcmp0(tokens[0], "inline") == 0) {
            if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_inline)) {
                fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
                return -1;
            }
        } else if (g_strcmp0(tokens[0], "idle") == 0) {
            if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &idle_report)) {
                fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
                return -1;
            }
        } else {
            fprintf(stderr, "option parsing failed: %s\n", opt);
            return -1;
        }
    }

    if (info->system_emulation && !do_inline) {
        max_cpus = info->system.max_vcpus;
        counts = g_ptr_array_new();
        for (i = 0; i < max_cpus; i++) {
            CPUCount *count = g_new0(CPUCount, 1);
            g_mutex_init(&count->lock);
            count->index = i;
            g_ptr_array_add(counts, count);
        }
    } else if (!do_inline) {
        g_mutex_init(&inline_count.lock);
    }

    if (idle_report) {
        qemu_plugin_register_vcpu_idle_cb(id, vcpu_idle);
    }

    qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
    qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
    return 0;
}
