//
// Created by gordon on 2024/5/31.
//

#ifndef ALIBABACLOUD_RUM_H
#define ALIBABACLOUD_RUM_H

#include <stdarg.h>
#include <stddef.h>
#include <inttypes.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifndef ALIBABACLOUD_RUM_NATIVE_NAME
#   define  ALIBABACLOUD_RUM_NATIVE_NAME "alibabacloud.rum.native"
#endif

//    SDK Version
#define ALIBABACLOUD_RUM_NATIVE_SDK_NAME "alibabacloud_rum"
#define ALIBABACLOUD_RUM_NATIVE_VERSION "0.4.1"
#define ALIBABACLOUD_RUM_NATIVE_USER_AGENT ALIBABACLOUD_RUM_NATIVE_SDK_NAME "/" ALIBABACLOUD_RUM_NATIVE_VERSION

#ifdef _WIN32
#   define ALIBABACLOUD_RUM_PLATFORM_WINDOWS
#elif defined(__APPLE__)

#   include <TargetConditionals.h>

#   if defined(TARGET_OS_OSX) && TARGET_OS_OSX
#       define ALIBABACLOUD_RUM_PLATFORM_MACOS
#   elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#       define ALIBABACLOUD_RUM_PLATFORM_IOS
#   endif
#   define ALIBABACLOUD_RUM_PLATFORM_DARWIN
#   define ALIBABACLOUD_RUM_PLATFORM_UNIX
#elif defined(__LINUX) || defined(__inux__)
#   define ALIBABACLOUD_RUM_PLATFORM_LINUX
#   define ALIBABACLOUD_RUM_PLATFORM_UNIX
#else
#   error unsupported platform
#endif

/* marks a function as part of the AlibabacloudRUM API*/
#ifndef ALIBABACLOUD_RUM_API
#   ifdef  _WIN32
#       if defined(ALIBABACLOUD_RUM_BUILD_SHARED)
#           define ALIBABACLOUD_RUM_API __declspec(dllexport)
#       elif !defined(ALIBABACLOUD_RUM_BUILD_STATIC)
#           define ALIBABACLOUD_RUM_API __declspec(dllimport)
#       else
#           define ALIBABACLOUD_RUM_API
#       endif
#   else
#       if __GNUC__ >= 4
#           define ALIBABACLOUD_RUM_API __attribute__((visibility("default")))
#       else
#           define ALIBABACLOUD_RUM_API
#       endif
#   endif
#endif

#if defined(__clang__)
#   define ALIBABACLOUD_RUM_UNUSED __attribute__((unused))
#elif defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
#   define ALIBABACLOUD_RUM_UNUSED __attribute__((unused))
#elif (defined(_MSC_VER) && _MSC_VER >= 1910) && (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
#   define ALIBABACLOUD_RUM_UNUSED [[maybe_unused]]
#else
#   define ALIBABACLOUD_RUM_UNUSED
#endif


#ifdef _WIN32
#   include <windows.h>
#else

#   include <signal.h>

#endif

#if defined(__GNUC__)
#    define UNUSED(x) UNUSED_##x __attribute__((__unused__))
#elif defined(_MSC_VER)
#    define UNUSED(x) UNUSED_##x __pragma(warning(suppress : 4100))
#else
#    define UNUSED(x) UNUSED_##x
#endif

#if defined(ALIBABACLOUD_RUM_PLATFORM_WINDOWS)
#define ALIBABACLOUD_RUM_CALLBACK __stdcall
#else
#define ALIBABACLOUD_RUM_CALLBACK
#endif

ALIBABACLOUD_RUM_API void *alibabacloud_rum_malloc(size_t size);

ALIBABACLOUD_RUM_API void *alibabacloud_rum_realloc(void* ptr, size_t size);

ALIBABACLOUD_RUM_API void alibabacloud_rum_free(void *ptr);

/**
 * The AlibabaCloud RUM Log Level.
 */
typedef enum alibabacloud_rum_level_e
{
    ALIBABACLOUD_RUM_LEVEL_FATAL = 1,
    ALIBABACLOUD_RUM_LEVEL_ERROR = 2,
    ALIBABACLOUD_RUM_LEVEL_WARNING = 3,
    ALIBABACLOUD_RUM_LEVEL_INFO = 4,
    ALIBABACLOUD_RUM_LEVEL_DEBUG = 5,
    ALIBABACLOUD_RUM_LEVEL_TRACE = 6,
    ALIBABACLOUD_RUM_LEVEL_ALL = 7,
} alibabacloud_rum_level_t;

typedef enum alibabacloud_rum_env_e
{
    ALIBABACLOUD_RUM_ENV_PROD = 1,
    ALIBABACLOUD_RUM_ENV_GRAY = 2,
    ALIBABACLOUD_RUM_ENV_PRE = 3,
    ALIBABACLOUD_RUM_ENV_DAILY = 4,
    ALIBABACLOUD_RUM_ENV_LOCAL = 5,
} alibabacloud_rum_env_t;

/**
 * The AlibabaCloud RUM logger function.
 */
typedef void(*alibabacloud_rum_logger_function_t)(
        alibabacloud_rum_level_t level, const char *message, va_list args, void *userdata
);

typedef void (*alibabacloud_rum_crash_function_t) (

);

typedef struct alibabacloud_rum_network_options_s
{
    int (ALIBABACLOUD_RUM_CALLBACK *should_record_request)(const char *url);
    int (ALIBABACLOUD_RUM_CALLBACK *should_tracing)(const char *url);
} alibabacloud_rum_network_options_t;

ALIBABACLOUD_RUM_API alibabacloud_rum_network_options_t *alibabacloud_rum_network_options_new(void);
ALIBABACLOUD_RUM_API void alibabacloud_rum_network_options_free(alibabacloud_rum_network_options_t *network_options);

/**
 * The AlibabaCloud RUM Options.
 */
struct alibabacloud_rum_options_s;
typedef struct alibabacloud_rum_options_s alibabacloud_rum_options_t;

/**
 * The AlibabaCloud RUM Options constructor.
 * @return
 */
ALIBABACLOUD_RUM_API alibabacloud_rum_options_t *alibabacloud_rum_options_new(void);

ALIBABACLOUD_RUM_API void alibabacloud_rum_options_free(alibabacloud_rum_options_t *);

/**
 * Set the AlibabaCloud RUM Config Address.
 * @param options
 * @param config_address
 */
ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_config_address(
        alibabacloud_rum_options_t *options,
        const char *config_address
);

/**
 * Set the AlibabaCloud RUM Application Id.
 * @param options
 * @param app_id
 */
ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_app_id(
        alibabacloud_rum_options_t *options,
        const char *app_id
);

/**
 * Set the AlibabaCloud RUM Application Name.
 * @param options
 * @param app_name
 */
ALIBABACLOUD_RUM_API void
alibabacloud_rum_options_set_app_name(alibabacloud_rum_options_t *options, const char *app_name);

void alibabacloud_rum__env_get_description(alibabacloud_rum_env_t env, char **description);
ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_env(alibabacloud_rum_options_t *options, alibabacloud_rum_env_t env);

ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_utdid(alibabacloud_rum_options_t *options, const char *utdid);

ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_app_version(
        alibabacloud_rum_options_t *options,
        const char *app_version);

ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_debug_level(alibabacloud_rum_options_t *options, alibabacloud_rum_level_t level);

ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_cache_path(alibabacloud_rum_options_t *options, const char *path);

ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_handler_path(alibabacloud_rum_options_t *options, const char *path);

ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_network_options(
        alibabacloud_rum_options_t *options, alibabacloud_rum_network_options_t *network_options);

/// Set whether to enable curl request tracking. Default is enable tracking.
/// \param options The {@link alibabacloud_rum_options_t}
/// \param enabled 0, disabled, otherwise enabled.
ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_auto_curl_tracking(alibabacloud_rum_options_t *options, int enabled);

/// Set whether to enable system crash tracking. Default is enable tracking.
/// \param options The {@link alibabacloud_rum_options_t}
/// \param enabled 0, disabled, otherwise enabled.
ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_auto_crash_tracking(alibabacloud_rum_options_t *options, int enabled);

/// Set whether to enable CEF web request tracking. Default is disable tracking.
/// \param options The {@link alibabacloud_rum_options_t}
/// \param enabled 0, disabled, otherwise enabled.
ALIBABACLOUD_RUM_API void alibabacloud_rum_options_set_auto_cef_tracking(alibabacloud_rum_options_t *options, int enabled);

ALIBABACLOUD_RUM_API void alibabacloud_rum_set_username(const char *username);

ALIBABACLOUD_RUM_API void alibabacloud_rum_set_userid(const char *userid);

ALIBABACLOUD_RUM_API void alibabacloud_rum_set_user_tags(const char *user_tags);

ALIBABACLOUD_RUM_API void alibabacloud_rum__set_properties(alibabacloud_rum_options_t *options, ...);

#define ALIBABACLOUD_RUM__EXPEND_SET_PROPERTIES(x) x
#define alibabacloud_rum_set_properties(...) \
    ALIBABACLOUD_RUM__EXPEND_SET_PROPERTIES(alibabacloud_rum__set_properties(NULL, __VA_ARGS__, NULL))

/**
 * The AlibabaCloud RUM initialization method.
 * @param options
 * @return
 */
ALIBABACLOUD_RUM_API int alibabacloud_rum_init(alibabacloud_rum_options_t *options);

ALIBABACLOUD_RUM_API int alibabacloud_rum_close(void);

ALIBABACLOUD_RUM_API void alibabacloud_rum_start_session(void);

ALIBABACLOUD_RUM_API void alibabacloud_rum_end_session(void);

// region custom event/log/exception
struct alibabacloud_rum_custom_event_s;
typedef struct alibabacloud_rum_custom_event_s alibabacloud_rum_custom_event_t;

ALIBABACLOUD_RUM_API alibabacloud_rum_custom_event_t* alibabacloud_rum_custom_event_new(const char *type, const char *name);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_event_set_value(alibabacloud_rum_custom_event_t *event, double value);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_event_set_group(alibabacloud_rum_custom_event_t *event, const char *group);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_event_set_snapshots(alibabacloud_rum_custom_event_t *event, const char *snapshots);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_event_add_extra(alibabacloud_rum_custom_event_t *event, const char *k, const  char *v);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_event_free(alibabacloud_rum_custom_event_t *event);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_event_report(alibabacloud_rum_custom_event_t *event);

// custom log start
struct alibabacloud_rum_custom_log_s;
typedef struct alibabacloud_rum_custom_log_s alibabacloud_rum_custom_log_t;
typedef enum
{
    ALIBABACLOUD_RUM_LOG_TRACE = 0,
    ALIBABACLOUD_RUM_LOG_DEBUG = 1,
    ALIBABACLOUD_RUM_LOG_INFO = 2,
    ALIBABACLOUD_RUM_LOG_WARN = 3,
    ALIBABACLOUD_RUM_LOG_ERROR = 4,
    ALIBABACLOUD_RUM_LOG_FATAL = 5
} alibabacloud_rum_custom_log_level_t;

ALIBABACLOUD_RUM_API alibabacloud_rum_custom_log_t *alibabacloud_rum_custom_log_new(const char *type, const char *name);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_log_set_log(alibabacloud_rum_custom_log_t *log,
                                                              alibabacloud_rum_custom_log_level_t level,
                                                              const char *content);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_log_set_value(alibabacloud_rum_custom_log_t *log, double value);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_log_set_group(alibabacloud_rum_custom_log_t *log, const char *group);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_log_set_snapshots(alibabacloud_rum_custom_log_t *log, const char *snapshots);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_log_add_extra(alibabacloud_rum_custom_log_t *log, const char *k, const char *v);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_log_free(alibabacloud_rum_custom_log_t *log);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_log_report(alibabacloud_rum_custom_log_t *log);

// custom exception start
struct alibabacloud_rum_custom_exception_s;
typedef struct alibabacloud_rum_custom_exception_s alibabacloud_rum_custom_exception_t;

ALIBABACLOUD_RUM_API alibabacloud_rum_custom_exception_t* alibabacloud_rum_custom_exception_new(const char *name, const char *message);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_exception_set_file(alibabacloud_rum_custom_exception_t *event, const char *file);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_exception_set_source(alibabacloud_rum_custom_exception_t *event, const char *source);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_exception_set_caused_by(alibabacloud_rum_custom_exception_t *event, const char *caused_by);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_exception_set_stack(alibabacloud_rum_custom_exception_t *event, const char *stack);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_exception_free(alibabacloud_rum_custom_exception_t *event);
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_exception_report(alibabacloud_rum_custom_exception_t *event);

// custom resource start
struct alibabacloud_rum_custom_resource_s;
typedef struct alibabacloud_rum_custom_resource_s alibabacloud_rum_custom_resource_t;

/// Resource type enumeration
typedef enum {
    ALIBABACLOUD_RUM_RESOURCE_TYPE_DOCUMENT,    // HTML documents
    ALIBABACLOUD_RUM_RESOURCE_TYPE_XHR,         // XMLHttpRequest / Fetch API
    ALIBABACLOUD_RUM_RESOURCE_TYPE_FETCH,       // Fetch API
    ALIBABACLOUD_RUM_RESOURCE_TYPE_BEACON,      // Beacon API
    ALIBABACLOUD_RUM_RESOURCE_TYPE_CSS,         // CSS files
    ALIBABACLOUD_RUM_RESOURCE_TYPE_JS,          // JavaScript files
    ALIBABACLOUD_RUM_RESOURCE_TYPE_IMAGE,       // Images (png, jpg, gif, etc)
    ALIBABACLOUD_RUM_RESOURCE_TYPE_FONT,        // Fonts
    ALIBABACLOUD_RUM_RESOURCE_TYPE_MEDIA,       // Audio/Video
    ALIBABACLOUD_RUM_RESOURCE_TYPE_OTHER        // Other resources
} alibabacloud_rum_resource_type_t;

/// Create a new custom resource event
/// \param url The resource URL
/// \param method HTTP method (GET, POST, etc)
/// \return A new custom resource event instance
ALIBABACLOUD_RUM_API alibabacloud_rum_custom_resource_t* alibabacloud_rum_custom_resource_new(const char *url, const char *method);

/// Set resource type
/// \param resource The custom resource event
/// \param type Resource type
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_set_type(alibabacloud_rum_custom_resource_t *resource, alibabacloud_rum_resource_type_t type);

/// Set HTTP status code
/// \param resource The custom resource event
/// \param status_code HTTP status code (e.g., 200, 404, 500)
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_set_status_code(alibabacloud_rum_custom_resource_t *resource, int32_t status_code);

/// Set whether the request was successful
/// \param resource The custom resource event
/// \param success 1 for success, 0 for failure
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_set_success(alibabacloud_rum_custom_resource_t *resource, int32_t success);

/// Set all performance measuring metrics at once
/// \param resource The custom resource event
/// \param duration Total duration in milliseconds
/// \param size Resource size in bytes
/// \param connect_duration TCP connection duration in milliseconds
/// \param ssl_duration SSL/TLS handshake duration in milliseconds
/// \param dns_duration DNS lookup duration in milliseconds
/// \param redirect_duration Redirect duration in milliseconds
/// \param first_byte_duration Time to first byte in milliseconds
/// \param download_duration Download duration in milliseconds
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_set_measuring(
    alibabacloud_rum_custom_resource_t *resource,
    int64_t duration,
    int64_t size,
    int32_t connect_duration,
    int32_t ssl_duration,
    int32_t dns_duration,
    int32_t redirect_duration,
    int32_t first_byte_duration,
    int32_t download_duration);

/// Set trace ID for distributed tracing
/// \param resource The custom resource event
/// \param trace_id Trace ID
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_set_trace_id(alibabacloud_rum_custom_resource_t *resource, const char *trace_id);

/// Set span ID for distributed tracing
/// \param resource The custom resource event
/// \param span_id Span ID
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_set_span_id(alibabacloud_rum_custom_resource_t *resource, const char *span_id);

/// Set provider information
/// \param resource The custom resource event
/// \param provider Provider name (e.g., "first-party", "cdn", "ad", "analytics")
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_set_provider(alibabacloud_rum_custom_resource_t *resource, const char *provider);

/// Add custom attribute to resource event
/// \param resource The custom resource event
/// \param key Attribute key
/// \param value Attribute value
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_add_attribute(alibabacloud_rum_custom_resource_t *resource, const char *key, const char *value);

/// Free custom resource event
/// \param resource The custom resource event to free
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_free(alibabacloud_rum_custom_resource_t *resource);

/// Report custom resource event
/// \param resource The custom resource event to report
ALIBABACLOUD_RUM_API void alibabacloud_rum_custom_resource_report(alibabacloud_rum_custom_resource_t *resource);
// endregion

// uuid start
typedef struct alibabacloud_rum_uuid_s {
    char bytes[16];
} alibabacloud_rum_uuid_t;

alibabacloud_rum_uuid_t alibabacloud_rum_uuid_new(void);
alibabacloud_rum_uuid_t alibabacloud_rum_uuid_nil(void);
alibabacloud_rum_uuid_t alibabacloud_rum_uuid_from_bytes(const char bytes[16]);
void alibabacloud_rum_uuid_as_string(alibabacloud_rum_uuid_t *uuid, char string[37]);
// uuid end
#ifdef __cplusplus
}
#endif
#endif //ALIBABACLOUD_RUM_H
