#pragma once

#include "SentryProfilingConditionals.h"

#if SENTRY_TARGET_PROFILING_SUPPORTED

#    include "SentryProfilingLogging.hpp"

#    include <mach/kern_return.h>
#    include <mach/message.h>

namespace sentry {
namespace profiling {

    /**
     * Returns a human readable description string for a kernel return code.
     *
     * @param kr The kernel return code to get a description for.
     * @return A string containing the description, or an unknown error message if
     * the error code is not known.
     */
    const char *kernelReturnCodeDescription(kern_return_t kr) noexcept;

    /**
     * Returns a human readable description string for a mach message return code.
     *
     * @param mr The mach message return code to get a description for.
     * @return A string containing the description, or an unknown error message if
     * the error code is not known.
     */
    const char *machMessageReturnCodeDescription(mach_msg_return_t mr) noexcept;

} // namespace profiling
} // namespace sentry

#    define SENTRY_PROF_LOG_KERN_RETURN(statement)                                                 \
        ({                                                                                         \
            const kern_return_t __log_kr = statement;                                              \
            if (__log_kr != KERN_SUCCESS) {                                                        \
                SENTRY_PROF_LOG_ERROR("%s failed with kern return code: %d, description: %s",      \
                    #statement, __log_kr,                                                          \
                    sentry::profiling::kernelReturnCodeDescription(__log_kr));                     \
            }                                                                                      \
            __log_kr;                                                                              \
        })

#    define SENTRY_PROF_LOG_MACH_MSG_RETURN(statement)                                             \
        ({                                                                                         \
            const mach_msg_return_t __log_mr = statement;                                          \
            if (__log_mr != MACH_MSG_SUCCESS) {                                                    \
                SENTRY_PROF_LOG_ERROR("%s failed with mach_msg return code: %d, description: %s",  \
                    #statement, __log_mr,                                                          \
                    sentry::profiling::machMessageReturnCodeDescription(__log_mr));                \
            }                                                                                      \
            __log_mr;                                                                              \
        })

#endif
