/*
 * 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 <psa/crypto.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)
{
	uint8_t sha_result[PSA_HASH_LENGTH(PSA_ALG_SHA_1)];
	psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
	size_t sha_len;
	psa_status_t status;

	if (out == NULL) {
		return -EINVAL;
	}

	status = psa_hash_setup(&hash_operation, PSA_ALG_SHA_1);
	if (status != PSA_SUCCESS) {
		goto exit;
	}

	status = psa_hash_update(&hash_operation, ns->val, UUID_SIZE);
	if (status != PSA_SUCCESS) {
		goto exit;
	}

	status = psa_hash_update(&hash_operation, data, data_size);
	if (status != PSA_SUCCESS) {
		goto exit;
	}

	status = psa_hash_finish(&hash_operation, sha_result, sizeof(sha_result), &sha_len);
	if (status != PSA_SUCCESS) {
		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:
	psa_hash_abort(&hash_operation);

	switch (status) {
	case PSA_SUCCESS:
		return 0;
	case PSA_ERROR_INSUFFICIENT_MEMORY:
		return -ENOMEM;
	case PSA_ERROR_NOT_SUPPORTED:
		return -ENOTSUP;
	default:
		return -EIO;
	}
}
#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
