#ifndef _SR_SDTDEF_H
#define _SR_SDTDEF_H

#include <stdint.h>

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __CLANG_ARM
#endif

/* Compiler Related Definitions */
#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM Compiler */
#include <stdarg.h>
#define SR_SECTION(x) __attribute__((section(x)))
#define SR_USED __attribute__((used))
#define SR_UNUSED __attribute__((unused))
#define SR_ALIGN(n) __attribute__((aligned(n)))
#define SR_WEAK __attribute__((weak))
#define SR_INLINE static __inline

#elif defined(__IAR_SYSTEMS_ICC__) /* for IAR Compiler */
#include <stdarg.h>
#define SR_SECTION(x) @x
#define SR_USED __root
#define SR_UNUSED
#define SR_PRAGMA(x) _Pragma(#x)
#define SR_ALIGN(n) SR_PRAGMA(data_alignment = n)
#define SR_WEAK __weak
#define SR_INLINE static inline  

#elif defined(__GNUC__) /* GNU GCC Compiler */
#include <stdarg.h>
#define SR_SECTION(x) __attribute__((section(x)))
#define SR_USED __attribute__((used))
#define SR_UNUSED __attribute__((unused))
#define SR_ALIGN(n) __attribute__((aligned(n)))
#define SR_WEAK __attribute__((weak))
#define SR_INLINE static __inline
#else
#error The compiler is not supported!
#endif

#define SR_NULL  0    /*!< 空值*/

#define SR_TRUE  1    /*!< 真*/
#define SR_FALSE 0    /*!< 假*/

#define SR_INVALID_U  0xFFFFFFF6U           /*!< 无效值 -10,与SR_INVALID对应*/
#define SR_IGNORE     0xFFFFFF9CU           /*!< 忽略*/

#define SR_UINT8_MAX  0xffU                 /*!< Maxium value of UINT8 */
#define SR_UINT16_MAX 0xffffU               /*!< Maxium value of UINT16 */
#define SR_UINT32_MAX 0xffffffffU           /*!< Maxium value of UINT32 */
#define SR_UINT64_MAX 0xffffffffffffffffULL /*!< Maxium value of UINT64 */


#ifdef SR_CPU_ARCH_64BIT
#define SR_TICK_MAX SR_UINT64_MAX /*!< Maxium value of tick */
#else
#define SR_TICK_MAX SR_UINT32_MAX /*!< Maxium value of tick */
#endif


/* Alignment size for CPU architecture data access */
#define SR_ALIGN_SIZE sizeof(srBase_t)

/* Basic data type definitions */
typedef int8_t srBool_t; /*!< Boolean type */

/* Represent Nbit CPU */
typedef signed long srBase_t;    /*!< Nbit CPU related date type */
typedef unsigned long srUbase_t; /*!< Nbit unsigned CPU related data type */

/* Else data type definitions */
typedef signed int srErr_t; /*!< Type for error number */
typedef srUbase_t srTick_t; /*!< Type for tick count */
typedef srUbase_t srSize_t; /*!< Type for size */
typedef srBase_t srSSize_t; /*!< Type for ssize */
typedef srBase_t srOff_t;   /*!< Type for offset */

/**
 ***********************************************************************************************************************
 * @def         SR_CONTAINER_OF
 *
 * @brief       Cast a member of a structure out to the containing structure.
 *
 * @param       ptr             The pointer to the member.
 * @param       type            The type of the container struct this is embedded in.
 * @param       member          The name of the member within the struct.
 ***********************************************************************************************************************
 */
#define SR_CONTAINER_OF(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

/*error code definitions */
#define SR_OK          0   /*!< There is no error. */
#define SR_FAIL       -1   /*!< A generic error happens. */
#define SR_TIMEOUT    -2   /*!< Timed out. */
#define SR_FULL       -3   /*!< The resource is full. */
#define SR_EMPTY      -4   /*!< The resource is empty. */
#define SR_NOMEM      -5   /*!< No memory. */
#define SR_NOIMPT     -6   /*!< Function not implemented. */
#define SR_BUSY       -7   /*!< Device or resource busy. */
#define SR_EIO        -8   /*!< IO error. */
#define SR_INTR       -9   /*!< Interrupted system call. */
#define SR_INVALID    -10  /*!< Invalid argument. */
#define SR_NOEXIST    -11  /*!< No such resources*/
#define SR_OPT_DENIED -12  /*!< Operation not permitted */
#define SR_ILL_ADDR   -13  /*!< illegal address */
#define SR_EKERNEL    -14  /*!< OS Kernel error */
#define SR_ENET       -15  /*!< 网络 error */
#define SR_EINIT      -16  /*!< 内部初始化错误 */
#define SR_ECALL      -17  /*!< 内部接口调用错误 */
#define SR_EBOUND     -18  /*!< 越界 */

// 断言
#ifdef SR_USE_ASSERT
#include "sr_log.h"
#define SR_ASSERT(condition)                                                                                    \
    do                                                                                                          \
    {                                                                                                           \
        if (!(condition))                                                                                       \
        {                                                                                                       \
            SR_LOG(ERR,"Assert failed. Condition(%s). [%s][%d]\r\n", #condition, __FUNCTION__, __LINE__); \
            return SR_INVALID;                                                                                  \
        }                                                                                                       \
    } while (0)

#define SR_ASSERT_EX(condition, fmt, ...)                                                                   \
    do                                                                                                      \
    {                                                                                                       \
        if (!(condition))                                                                                   \
        {                                                                                                   \
            SR_LOG(ERR,"Assert failed. " fmt " [%s][%d]\r\n", ##__VA_ARGS__, __FUNCTION__, __LINE__); \
            return SR_INVALID;                                                                              \
        }                                                                                                   \
    } while (0)

#define SR_ASSERT_WHILE(condition)                                                                              \
    do                                                                                                          \
    {                                                                                                           \
        if (!(condition))                                                                                       \
        {                                                                                                       \
            SR_LOG(ERR,"Assert failed. Condition(%s). [%s][%d]\r\n", #condition, __FUNCTION__, __LINE__); \
            while(1);                                                                                  \
        }                                                                                                       \
    } while (0)


#else
#define SR_ASSERT(condition)
#define SR_ASSERT_EX(condition, fmt, ...)
#define SR_ASSERT_WHILE(condition)

#endif /* SR_USE_ASSERT */

/*-----------自动初始化机制---------*/
// 子优先级
#define SR_PRIORITY_0 "1"
#define SR_PRIORITY_1 "2"
#define SR_PRIORITY_2 "3"

// 自动初始化函数类型
typedef int (*init_func_t)(void);

// 自动初始化宏定义申明
#define SR_INIT_EXPORT(func, location, priority) SR_USED const init_func_t _sr_init_##func SR_SECTION(location priority) = func
/*early BSP、device I/O framework initialization*/
#define SR_INIT_BSP_EXPORT(func, priority) SR_INIT_EXPORT(func, ".sunrise.bsp_init.", priority)

/* components initialization (net,cloud, ...) */
#define SR_INIT_COMPONENT_EXPORT(func, priority) SR_INIT_EXPORT(func, ".sunrise.component_init.", priority)

/* appliation initialization (user application etc ...) */
#define SR_INIT_APP_EXPORT(func, priority) SR_INIT_EXPORT(func, ".sunrise.app_init.", priority)

// 周期调度任务
typedef struct
{
    void (*func)(void);      // 任务函数
    unsigned int lastTick;   // 保存上次tick
    unsigned short periodMs; // 任务轮询周期

} poll_task_t;

/**
 * @brief  周期轮询任务声明
 * @param  func        - 任务函数
 * @param  period10Ms  - 轮询间隔(单位 10ms)
 * @param  priority    - 优先级
 */
#define SR_POLL_TASK_EXPORT(func, period10Ms, priority) \
    SR_USED poll_task_t _sr_poll_##func SR_SECTION(".sunrise.poll_task." priority) = {func, 0, period10Ms}

#endif
