/*
 *  QEMU NVMe NGUID functions
 *
 * Copyright 2024 Google LLC
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 */

#include "qemu/osdep.h"
#include "qapi/visitor.h"
#include "qemu/ctype.h"
#include "nvme.h"

#define NGUID_SEPARATOR '-'

#define NGUID_VALUE_AUTO "auto"

#define NGUID_FMT              \
    "%02hhx%02hhx%02hhx%02hhx" \
    "%02hhx%02hhx%02hhx%02hhx" \
    "%02hhx%02hhx%02hhx%02hhx" \
    "%02hhx%02hhx%02hhx%02hhx"

#define NGUID_STR_LEN (2 * NGUID_LEN + 1)

bool nvme_nguid_is_null(const NvmeNGUID *nguid)
{
    static NvmeNGUID null_nguid;
    return memcmp(nguid, &null_nguid, sizeof(NvmeNGUID)) == 0;
}

static void nvme_nguid_generate(NvmeNGUID *out)
{
    int i;
    uint32_t x;

    QEMU_BUILD_BUG_ON((NGUID_LEN % sizeof(x)) != 0);

    for (i = 0; i < NGUID_LEN; i += sizeof(x)) {
        x = g_random_int();
        memcpy(&out->data[i], &x, sizeof(x));
    }
}

/*
 * The Linux Kernel typically prints the NGUID of an NVMe namespace using the
 * same format as the UUID. For instance:
 *
 * $ cat /sys/class/block/nvme0n1/nguid
 * e9accd3b-8390-4e13-167c-f0593437f57d
 *
 * When there is no UUID but there is NGUID the Kernel will print the NGUID as
 * wwid and it won't use the UUID format:
 *
 * $ cat /sys/class/block/nvme0n1/wwid
 * eui.e9accd3b83904e13167cf0593437f57d
 *
 * The NGUID has different fields compared to the UUID, so the grouping used in
 * the UUID format has no relation with the 3 fields of the NGUID.
 *
 * This implementation won't expect a strict format as the UUID one and instead
 * it will admit any string of hexadecimal digits. Byte groups could be created
 * using the '-' separator. The number of bytes needs to be exactly 16 and the
 * separator '-' has to be exactly in a byte boundary. The following are
 * examples of accepted formats for the NGUID string:
 *
 * nguid="e9accd3b-8390-4e13-167c-f0593437f57d"
 * nguid="e9accd3b83904e13167cf0593437f57d"
 * nguid="FEDCBA9876543210-ABCDEF-0123456789"
 */
static bool nvme_nguid_is_valid(const char *str)
{
    int i;
    int digit_count = 0;

    for (i = 0; i < strlen(str); i++) {
        const char c = str[i];
        if (qemu_isxdigit(c)) {
            digit_count++;
            continue;
        }
        if (c == NGUID_SEPARATOR) {
            /*
             * We need to make sure the separator is in a byte boundary, the
             * string does not start with the separator and they are not back to
             * back "--".
             */
            if ((i > 0) && (str[i - 1] != NGUID_SEPARATOR) &&
                (digit_count % 2) == 0) {
                continue;
            }
        }
        return false;
    }
    /*
     * The string should have the correct byte length and not finish with the
     * separator
     */
    return (digit_count == (2 * NGUID_LEN)) && (str[i - 1] != NGUID_SEPARATOR);
}

static int nvme_nguid_parse(const char *str, NvmeNGUID *nguid)
{
    uint8_t *id = &nguid->data[0];
    int ret = 0;
    int i;
    const char *ptr = str;

    if (!nvme_nguid_is_valid(str)) {
        return -1;
    }

    for (i = 0; i < NGUID_LEN; i++) {
        ret = sscanf(ptr, "%02hhx", &id[i]);
        if (ret != 1) {
            return -1;
        }
        ptr += 2;
        if (*ptr == NGUID_SEPARATOR) {
            ptr++;
        }
    }

    return 0;
}

/*
 * When converted back to string this implementation will use a raw hex number
 * with no separators, for instance:
 *
 * "e9accd3b83904e13167cf0593437f57d"
 */
static void nvme_nguid_stringify(const NvmeNGUID *nguid, char *out)
{
    const uint8_t *id = &nguid->data[0];
    snprintf(out, NGUID_STR_LEN, NGUID_FMT,
             id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7],
             id[8], id[9], id[10], id[11], id[12], id[13], id[14], id[15]);
}

static void get_nguid(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    Property *prop = opaque;
    NvmeNGUID *nguid = object_field_prop_ptr(obj, prop);
    char buffer[NGUID_STR_LEN];
    char *p = buffer;

    nvme_nguid_stringify(nguid, buffer);

    visit_type_str(v, name, &p, errp);
}

static void set_nguid(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
{
    Property *prop = opaque;
    NvmeNGUID *nguid = object_field_prop_ptr(obj, prop);
    char *str;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    if (!strcmp(str, NGUID_VALUE_AUTO)) {
        nvme_nguid_generate(nguid);
    } else if (nvme_nguid_parse(str, nguid) < 0) {
        error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
    }
    g_free(str);
}

const PropertyInfo qdev_prop_nguid = {
    .name  = "str",
    .description =
        "NGUID or \"" NGUID_VALUE_AUTO "\" for random value",
    .get   = get_nguid,
    .set   = set_nguid,
};
