// vim:fileencoding=utf-8:foldmethod=marker

#ifndef UUID_H
#define UUID_H

#include "../common/aliases/aliases.h"
#include "../common/platform/platform.h"
#include "../base/strings/str8/str8.h"

#ifdef WP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP

#define WP_UUID_BUF_LENGTH 48
#define WP_UUID_SPEC WP_STR8_SPEC
#define wpUuidVarg(WpUuid) wpStr8Varg((WpUuid).uuid)

typedef struct WpUuid WpUuid;
struct WpUuid {
	WpStr8 uuid;
};

// TODO (Abdelrahman): Update UUID implementation to work properly with C++ and tests for validation

#ifdef WP_PLATFORM_CPP
#define wpUuidGenUuid4() ([&](){           \
	wp_persist WpUuid uuid = wpUuidCreate(); \
	return *(wpUuidInitUuid4(&uuid));        \
}())
#else
#define wpUuidGenUuid4() *(wpUuidInitUuid4(&wpUuidCreate()))
#endif

/* Low level UUID API */

#ifdef WP_PLATFORM_CPP
#define wpUuidCreate() ([&](){ return WpUuid{wpStr8Buf(WP_UUID_BUF_LENGTH)}; }())
#else
#define wpUuidCreate() ((WpUuid){.uuid = wpStr8Buf(WP_UUID_BUF_LENGTH)})
#endif

// Just returns the same pointer that was passed in with the UUID initialised.
// Fails when passed a NULL pointer.
WpUuid *wpUuidInitUuid4(WpUuid *uuid);

#ifdef WP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WP_PLATFORM_CPP

#endif // !UUID_H
