/*
 * QEMU KVM support -- x86 virtual RAPL msr
 *
 * Copyright 2024 Red Hat, Inc. 2024
 *
 *  Author:
 *      Anthony Harivel <aharivel@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "vmsr_energy.h"
#include "io/channel.h"
#include "io/channel-socket.h"
#include "hw/boards.h"
#include "cpu.h"
#include "host-cpu.h"

char *vmsr_compute_default_paths(void)
{
    g_autofree char *state = qemu_get_local_state_dir();

    return g_build_filename(state, "run", "qemu-vmsr-helper.sock", NULL);
}

bool is_host_cpu_intel(void)
{
    int family, model, stepping;
    char vendor[CPUID_VENDOR_SZ + 1];

    host_cpu_vendor_fms(vendor, &family, &model, &stepping);

    return strcmp(vendor, CPUID_VENDOR_INTEL);
}

int is_rapl_enabled(void)
{
    const char *path = "/sys/class/powercap/intel-rapl/enabled";
    FILE *file = fopen(path, "r");
    int value = 0;

    if (file != NULL) {
        if (fscanf(file, "%d", &value) != 1) {
            error_report("INTEL RAPL not enabled");
        }
        fclose(file);
    } else {
        error_report("Error opening %s", path);
    }

    return value;
}

QIOChannelSocket *vmsr_open_socket(const char *path)
{
    g_autofree char *socket_path = NULL;

    socket_path = g_strdup(path);

    SocketAddress saddr = {
        .type = SOCKET_ADDRESS_TYPE_UNIX,
        .u.q_unix.path = socket_path
    };

    QIOChannelSocket *sioc = qio_channel_socket_new();
    Error *local_err = NULL;

    qio_channel_set_name(QIO_CHANNEL(sioc), "vmsr-helper");
    qio_channel_socket_connect_sync(sioc,
                                    &saddr,
                                    &local_err);
    if (local_err) {
        /* Close socket. */
        qio_channel_close(QIO_CHANNEL(sioc), NULL);
        object_unref(OBJECT(sioc));
        sioc = NULL;
        goto out;
    }

    qio_channel_set_delay(QIO_CHANNEL(sioc), false);
out:
    return sioc;
}

uint64_t vmsr_read_msr(uint32_t reg, uint32_t cpu_id, uint32_t tid,
                       QIOChannelSocket *sioc)
{
    uint64_t data = 0;
    int r = 0;
    Error *local_err = NULL;
    uint32_t buffer[3];
    /*
     * Send the required arguments:
     * 1. RAPL MSR register to read
     * 2. On which CPU ID
     * 3. From which vCPU (Thread ID)
     */
    buffer[0] = reg;
    buffer[1] = cpu_id;
    buffer[2] = tid;

    r = qio_channel_write_all(QIO_CHANNEL(sioc),
                              (char *)buffer, sizeof(buffer),
                              &local_err);
    if (r < 0) {
        goto out_close;
    }

    r = qio_channel_read(QIO_CHANNEL(sioc),
                             (char *)&data, sizeof(data),
                             &local_err);
    if (r < 0) {
        data = 0;
        goto out_close;
    }

out_close:
   return data;
}

/* Retrieve the max number of physical package */
unsigned int vmsr_get_max_physical_package(unsigned int max_cpus)
{
    const char *dir = "/sys/devices/system/cpu/";
    const char *topo_path = "topology/physical_package_id";
    g_autofree int *uniquePackages = g_new0(int, max_cpus);
    unsigned int packageCount = 0;
    FILE *file = NULL;

    for (int i = 0; i < max_cpus; i++) {
        g_autofree char *filePath = NULL;
        g_autofree char *cpuid = g_strdup_printf("cpu%d", i);

        filePath = g_build_filename(dir, cpuid, topo_path, NULL);

        file = fopen(filePath, "r");

        if (file == NULL) {
            error_report("Error opening physical_package_id file");
            return 0;
        }

        char packageId[10];
        if (fgets(packageId, sizeof(packageId), file) == NULL) {
            packageCount = 0;
        }

        fclose(file);

        int currentPackageId = atoi(packageId);

        bool isUnique = true;
        for (int j = 0; j < packageCount; j++) {
            if (uniquePackages[j] == currentPackageId) {
                isUnique = false;
                break;
            }
        }

        if (isUnique) {
            uniquePackages[packageCount] = currentPackageId;
            packageCount++;

            if (packageCount >= max_cpus) {
                break;
            }
        }
    }

    return (packageCount == 0) ? 1 : packageCount;
}

/* Retrieve the max number of physical cpu on the host */
unsigned int vmsr_get_maxcpus(void)
{
    GDir *dir;
    const gchar *entry_name;
    unsigned int cpu_count = 0;
    const char *path = "/sys/devices/system/cpu/";

    dir = g_dir_open(path, 0, NULL);
    if (dir == NULL) {
        error_report("Unable to open cpu directory");
        return -1;
    }

    while ((entry_name = g_dir_read_name(dir)) != NULL) {
        if (g_ascii_strncasecmp(entry_name, "cpu", 3) == 0 &&
            isdigit(entry_name[3])) {
            cpu_count++;
        }
    }

    g_dir_close(dir);

    return cpu_count;
}

/* Count the number of physical cpu on each packages */
unsigned int vmsr_count_cpus_per_package(unsigned int *package_count,
                                         unsigned int max_pkgs)
{
    g_autofree char *file_contents = NULL;
    g_autofree char *path = NULL;
    g_autofree char *path_name = NULL;
    gsize length;

    /* Iterate over cpus and count cpus in each package */
    for (int cpu_id = 0; ; cpu_id++) {
        path_name = g_strdup_printf("/sys/devices/system/cpu/cpu%d/"
            "topology/physical_package_id", cpu_id);

        path = g_build_filename(path_name, NULL);

        if (!g_file_get_contents(path, &file_contents, &length, NULL)) {
            break; /* No more cpus */
        }

        /* Get the physical package ID for this CPU */
        int package_id = atoi(file_contents);

        /* Check if the package ID is within the known number of packages */
        if (package_id >= 0 && package_id < max_pkgs) {
            /* If yes, count the cpu for this package*/
            package_count[package_id]++;
        }
    }

    return 0;
}

/* Get the physical package id from a given cpu id */
int vmsr_get_physical_package_id(int cpu_id)
{
    g_autofree char *file_contents = NULL;
    g_autofree char *file_path = NULL;
    int package_id = -1;
    gsize length;

    file_path = g_strdup_printf("/sys/devices/system/cpu/cpu%d"
        "/topology/physical_package_id", cpu_id);

    if (!g_file_get_contents(file_path, &file_contents, &length, NULL)) {
        goto out;
    }

    package_id = atoi(file_contents);

out:
    return package_id;
}

/* Read the scheduled time for a given thread of a give pid */
void vmsr_read_thread_stat(pid_t pid,
                      unsigned int thread_id,
                      unsigned long long *utime,
                      unsigned long long *stime,
                      unsigned int *cpu_id)
{
    g_autofree char *path = NULL;
    g_autofree char *path_name = NULL;

    path_name = g_strdup_printf("/proc/%u/task/%d/stat", pid, thread_id);

    path = g_build_filename(path_name, NULL);

    FILE *file = fopen(path, "r");
    if (file == NULL) {
        error_report("Error opening %s", path_name);
        return;
    }

    if (fscanf(file, "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u"
        " %llu %llu %*d %*d %*d %*d %*d %*d %*u %*u %*d %*u %*u"
        " %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %*u %*u %u",
           utime, stime, cpu_id) != 3)
    {
        fclose(file);
        error_report("Error fscanf did not report the right amount of items");
        return;
    }

    fclose(file);
    return;
}

/* Read QEMU stat task folder to retrieve all QEMU threads ID */
pid_t *vmsr_get_thread_ids(pid_t pid, unsigned int *num_threads)
{
    g_autofree char *task_path = g_strdup_printf("%d/task", pid);
    g_autofree char *path = g_build_filename("/proc", task_path, NULL);

    DIR *dir = opendir(path);
    if (dir == NULL) {
        error_report("Error opening /proc/qemu/task");
        return NULL;
    }

    pid_t *thread_ids = NULL;
    unsigned int thread_count = 0;

    g_autofree struct dirent *ent = NULL;
    while ((ent = readdir(dir)) != NULL) {
        if (ent->d_name[0] == '.') {
            continue;
        }
        pid_t tid = atoi(ent->d_name);
        if (pid != tid) {
            thread_ids = g_renew(pid_t, thread_ids, (thread_count + 1));
            thread_ids[thread_count] = tid;
            thread_count++;
        }
    }

    closedir(dir);

    *num_threads = thread_count;
    return thread_ids;
}

void vmsr_delta_ticks(vmsr_thread_stat *thd_stat, int i)
{
    thd_stat[i].delta_ticks = (thd_stat[i].utime[1] + thd_stat[i].stime[1])
                            - (thd_stat[i].utime[0] + thd_stat[i].stime[0]);
}

double vmsr_get_ratio(uint64_t e_delta,
                      unsigned long long delta_ticks,
                      unsigned int maxticks)
{
    return (e_delta / 100.0) * ((100.0 / maxticks) * delta_ticks);
}

void vmsr_init_topo_info(X86CPUTopoInfo *topo_info,
                           const MachineState *ms)
{
    topo_info->dies_per_pkg = ms->smp.dies;
    topo_info->modules_per_die = ms->smp.modules;
    topo_info->cores_per_module = ms->smp.cores;
    topo_info->threads_per_core = ms->smp.threads;
}

