/*
 * Copyright (c) 2025, SECO Mind Srl
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/sys/uuid.h>

#include <ctype.h>
#include <string.h>
#include <stdio.h>

#if defined(CONFIG_UUID_V4)
#include <zephyr/random/random.h>
#endif

#if defined(CONFIG_UUID_V5)
#include <mbedtls/md.h>
#endif

#if defined(CONFIG_UUID_BASE64)
#include <zephyr/sys/base64.h>
#endif

#define UUID_STR_POSITION_FIRST_HYPHEN  (8U)
#define UUID_STR_POSITION_SECOND_HYPHEN (13U)
#define UUID_STR_POSITION_THIRD_HYPHEN  (18U)
#define UUID_STR_POSITION_FOURTH_HYPHEN (23U)

#define UUID_POSITION_VERSION (6U)
#define UUID_OFFSET_VERSION   (4U)
#define UUID_MASK_VERSION     (0xF0U)
#define UUID_POSITION_VARIANT (8U)
#define UUID_OFFSET_VARIANT   (6U)
#define UUID_MASK_VARIANT     (0xC0)

#define UUID_V4_VERSION (4U)
#define UUID_V4_VARIANT (2U)
#define UUID_V5_VERSION (5U)
#define UUID_V5_VARIANT (2U)

#if defined(CONFIG_UUID_V4) || defined(CONFIG_UUID_V5)
static void overwrite_uuid_version_and_variant(uint8_t version, uint8_t variant, struct uuid *out)
{
	/* Clear the 'ver' and 'var' fields */
	out->val[UUID_POSITION_VERSION] &= ~UUID_MASK_VERSION;
	out->val[UUID_POSITION_VARIANT] &= ~UUID_MASK_VARIANT;
	/* Update the 'ver' and 'var' fields */
	out->val[UUID_POSITION_VERSION] |= (uint8_t)(version << UUID_OFFSET_VERSION);
	out->val[UUID_POSITION_VARIANT] |= (uint8_t)(variant << UUID_OFFSET_VARIANT);
}
#endif

static bool should_be_hyphen(unsigned int position)
{
	switch (position) {
	case UUID_STR_POSITION_FIRST_HYPHEN:
	case UUID_STR_POSITION_SECOND_HYPHEN:
	case UUID_STR_POSITION_THIRD_HYPHEN:
	case UUID_STR_POSITION_FOURTH_HYPHEN:
		return true;
	default:
		return false;
	}
}

#if defined(CONFIG_UUID_V4)
int uuid_generate_v4(struct uuid *out)
{
	if (out == NULL) {
		return -EINVAL;
	}
	/* Fill the whole UUID struct with a random number */
	sys_rand_get(out->val, UUID_SIZE);
	/* Update version and variant */
	overwrite_uuid_version_and_variant(UUID_V4_VERSION, UUID_V4_VARIANT, out);
	return 0;
}
#endif

#if defined(CONFIG_UUID_V5)
int uuid_generate_v5(const struct uuid *ns, const void *data, size_t data_size,
		     struct uuid *out)
{
	if (out == NULL) {
		return -EINVAL;
	}
	int ret = 0;
	int mbedtls_err = 0;
	mbedtls_md_context_t ctx = {0};
	const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
	const size_t sha_1_bytes = 20;
	uint8_t sha_result[sha_1_bytes];

	mbedtls_md_init(&ctx);
	mbedtls_err = mbedtls_md_setup(&ctx, md_info, 0);
	/* Might return: MBEDTLS_ERR_MD_BAD_INPUT_DATA or MBEDTLS_ERR_MD_ALLOC_FAILED */
	switch (mbedtls_err) {
	case 0:
		break;
	case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
		ret = -EINVAL;
		goto exit;
	case MBEDTLS_ERR_MD_ALLOC_FAILED:
		ret = -ENOMEM;
		goto exit;
	default:
		ret = -ENOTSUP;
		goto exit;
	}
	mbedtls_err = mbedtls_md_starts(&ctx);
	if (mbedtls_err != 0) {
		/* Might return MBEDTLS_ERR_MD_BAD_INPUT_DATA */
		ret = -EINVAL;
		goto exit;
	}
	mbedtls_err = mbedtls_md_update(&ctx, ns->val, UUID_SIZE);
	if (mbedtls_err != 0) {
		/* Might return MBEDTLS_ERR_MD_BAD_INPUT_DATA */
		ret = -EINVAL;
		goto exit;
	}
	mbedtls_err = mbedtls_md_update(&ctx, data, data_size);
	if (mbedtls_err != 0) {
		/* Might return MBEDTLS_ERR_MD_BAD_INPUT_DATA */
		ret = -EINVAL;
		goto exit;
	}
	mbedtls_err = mbedtls_md_finish(&ctx, sha_result);
	if (mbedtls_err != 0) {
		/* Might return MBEDTLS_ERR_MD_BAD_INPUT_DATA */
		ret = -EINVAL;
		goto exit;
	}

	/* Store the computed SHA1 in the out struct */
	for (unsigned int i = 0; i < UUID_SIZE; i++) {
		out->val[i] = sha_result[i];
	}
	/* Update version and variant */
	overwrite_uuid_version_and_variant(UUID_V5_VERSION, UUID_V5_VARIANT, out);

exit:
	mbedtls_md_free(&ctx);
	return ret;
}
#endif

int uuid_copy(const struct uuid *data, struct uuid *out)
{
	if (out == NULL) {
		return -EINVAL;
	}
	memcpy(out->val, data->val, UUID_SIZE);
	return 0;
}

int uuid_from_buffer(const uint8_t data[UUID_SIZE], struct uuid *out)
{
	if ((data == NULL) || (out == NULL)) {
		return -EINVAL;
	}
	memcpy(out->val, data, UUID_SIZE);
	return 0;
}

int uuid_from_string(const char data[UUID_STR_LEN], struct uuid *out)
{
	if ((data == NULL) || (strlen(data) + 1 != UUID_STR_LEN) || (out == NULL)) {
		return -EINVAL;
	}
	for (unsigned int i = 0; i < UUID_STR_LEN - 1; i++) {
		char char_i = data[i];
		/* Check that hyphens are in the right place */
		if (should_be_hyphen(i)) {
			if (char_i != '-') {
				return -EINVAL;
			}
			continue;
		}
		/* Check if the given input is hexadecimal */
		if (!isxdigit(char_i)) {
			return -EINVAL;
		}
	}

	/* Content parsing */
	unsigned int data_idx = 0U;
	unsigned int out_idx = 0U;

	while (data_idx < UUID_STR_LEN - 1) {
		if (should_be_hyphen(data_idx)) {
			data_idx += 1;
			continue;
		}

		size_t hex2bin_rc =
			hex2bin(&data[data_idx], 2, &out->val[out_idx], UUID_SIZE - out_idx);
		if (hex2bin_rc != 1) {
			return -EINVAL;
		}
		out_idx++;
		data_idx += 2;
	}
	return 0;
}

int uuid_to_buffer(const struct uuid *data, uint8_t out[UUID_SIZE])
{
	if (out == NULL) {
		return -EINVAL;
	}
	memcpy(out, data->val, UUID_SIZE);
	return 0;
}

int uuid_to_string(const struct uuid *data, char out[UUID_STR_LEN])
{
	if (out == NULL) {
		return -EINVAL;
	}
	snprintf(out, UUID_STR_LEN,
		 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
		 data->val[0], data->val[1], data->val[2], data->val[3], data->val[4], data->val[5],
		 data->val[6], data->val[7], data->val[8], data->val[9], data->val[10],
		 data->val[11], data->val[12], data->val[13], data->val[14], data->val[15]);
	return 0;
}

#if defined(CONFIG_UUID_BASE64)
int uuid_to_base64(const struct uuid *data, char out[UUID_BASE64_LEN])
{
	if (out == NULL) {
		return -EINVAL;
	}

	size_t olen = 0;

	base64_encode(out, UUID_BASE64_LEN, &olen, data->val, UUID_SIZE);
	return 0;
}

int uuid_to_base64url(const struct uuid *data, char out[UUID_BASE64URL_LEN])
{
	if (out == NULL) {
		return -EINVAL;
	}

	/* Convert UUID to RFC 3548/4648 base 64 notation */
	size_t olen = 0;
	char uuid_base64[UUID_BASE64_LEN] = {0};

	base64_encode(uuid_base64, UUID_BASE64_LEN, &olen, data->val, UUID_SIZE);
	/* Convert UUID to RFC 4648 sec. 5 URL and filename safe base 64 notation */
	for (unsigned int i = 0; i < UUID_BASE64URL_LEN - 1; i++) {
		if (uuid_base64[i] == '+') {
			uuid_base64[i] = '-';
		}
		if (uuid_base64[i] == '/') {
			uuid_base64[i] = '_';
		}
	}
	memcpy(out, uuid_base64, UUID_BASE64URL_LEN - 1);
	out[UUID_BASE64URL_LEN - 1] = 0;
	return 0;
}
#endif
