/**
 * @file    myBase.h
 * @brief   公共基础定义 — 所有模块共享的宏、类型、常量
 * @details 从零编写，功能对齐 RTU 原工程。
 *          包含：终端颜色、字节序转换、数据类型常量等。
 */

#ifndef _MY_BASE_H_
#define _MY_BASE_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>

#ifdef __cplusplus
extern "C"
{
#endif

/* === 终端颜色码 === */
#define COLOR_RESET   "\033[0m"
#define COLOR_RED     "\033[31m"
#define COLOR_GREEN   "\033[32m"
#define COLOR_YELLOW  "\033[33m"
#define COLOR_BLUE    "\033[34m"
#define COLOR_MAGENTA "\033[35m"
#define COLOR_CYAN    "\033[36m"
#define COLOR_WHITE   "\033[37m"

/* === 文件名缩写（去除路径前缀，跨平台兼容） === */
#if defined(__linux__)
#define __SHORT_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#else
#define __SHORT_FILE__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#endif

/* === 简易控制台日志宏（liblog 加载前可用） === */
#define MY_LOG(color, level, fmt, ...) \
    do \
    { \
        struct timeval _tv; \
        gettimeofday(&_tv, NULL); \
        struct tm *_tm = localtime(&_tv.tv_sec); \
        printf("%s[%04d-%02d-%02d %02d:%02d:%02d.%03d] [%s] [%s, %u] " fmt COLOR_RESET "\n", \
               color, \
               _tm ? _tm->tm_year + 1900 : 0, _tm ? _tm->tm_mon + 1 : 0, _tm ? _tm->tm_mday : 0, \
               _tm ? _tm->tm_hour : 0, _tm ? _tm->tm_min : 0, _tm ? _tm->tm_sec : 0, \
               (int)(_tv.tv_usec / 1000), \
               level, __SHORT_FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

#define MY_LOG_I(fmt, ...) MY_LOG(COLOR_WHITE, "INFO", fmt, ##__VA_ARGS__)
#define MY_LOG_E(fmt, ...) MY_LOG(COLOR_RED, "ERROR", fmt, ##__VA_ARGS__)

/* === LOCAL 修饰符（语义：文件内可见，等价于 static） === */
#ifndef LOCAL
#define LOCAL static
#endif

/* === 定长字符串类型 === */
#define SHORT_STR_LEN 64
typedef char S_STR[SHORT_STR_LEN];

#define LONG_STR_LEN 128
typedef char L_STR[LONG_STR_LEN];

/* === 字节序转换：uint16 === */
#define BE16_GET(p)  ((uint16_t)(((uint8_t *)(p))[0] << 8 | ((uint8_t *)(p))[1]))
#define BE16_SET(m, n) ((m)[0] = (uint8_t)((n) >> 8), (m)[1] = (uint8_t)(n))
#define LE16_GET(p)  ((uint16_t)(((uint8_t *)(p))[1] << 8 | ((uint8_t *)(p))[0]))
#define LE16_SET(m, n) ((m)[0] = (uint8_t)(n), (m)[1] = (uint8_t)((n) >> 8))

/* === 字节序转换：int32 === */
#define BE32_GET(p)  ((int32_t)(((uint8_t *)(p))[0] << 24 | ((uint8_t *)(p))[1] << 16 | ((uint8_t *)(p))[2] << 8 | ((uint8_t *)(p))[3]))
#define BE32_SET(m, n) ((m)[0] = (uint8_t)((n) >> 24), (m)[1] = (uint8_t)((n) >> 16), (m)[2] = (uint8_t)((n) >> 8), (m)[3] = (uint8_t)(n))
#define LE32_GET(p)  ((int32_t)(((uint8_t *)(p))[3] << 24 | ((uint8_t *)(p))[2] << 16 | ((uint8_t *)(p))[1] << 8 | ((uint8_t *)(p))[0]))
#define LE32_SET(m, n) ((m)[3] = (uint8_t)((n) >> 24), (m)[2] = (uint8_t)((n) >> 16), (m)[1] = (uint8_t)((n) >> 8), (m)[0] = (uint8_t)(n))

/* === 字节序转换：uint64 === */
#define BE64_GET(p)  (((uint64_t)(((uint8_t *)(p))[0]) << 56) | ((uint64_t)(((uint8_t *)(p))[1]) << 48) | ((uint64_t)(((uint8_t *)(p))[2]) << 40) | ((uint64_t)(((uint8_t *)(p))[3]) << 32) | ((uint64_t)(((uint8_t *)(p))[4]) << 24) | ((uint64_t)(((uint8_t *)(p))[5]) << 16) | ((uint64_t)(((uint8_t *)(p))[6]) << 8)  | ((uint64_t)(((uint8_t *)(p))[7])))
#define LE64_GET(p)  (((uint64_t)(((uint8_t *)(p))[7]) << 56) | ((uint64_t)(((uint8_t *)(p))[6]) << 48) | ((uint64_t)(((uint8_t *)(p))[5]) << 40) | ((uint64_t)(((uint8_t *)(p))[4]) << 32) | ((uint64_t)(((uint8_t *)(p))[3]) << 24) | ((uint64_t)(((uint8_t *)(p))[2]) << 16) | ((uint64_t)(((uint8_t *)(p))[1]) << 8)  | ((uint64_t)(((uint8_t *)(p))[0])))

#define BE64_SET(m, n) ((m)[0] = (uint8_t)((n) >> 56), (m)[1] = (uint8_t)((n) >> 48), (m)[2] = (uint8_t)((n) >> 40), (m)[3] = (uint8_t)((n) >> 32), (m)[4] = (uint8_t)((n) >> 24), (m)[5] = (uint8_t)((n) >> 16), (m)[6] = (uint8_t)((n) >> 8), (m)[7] = (uint8_t)(n))
#define LE64_SET(m, n) ((m)[7] = (uint8_t)((n) >> 56), (m)[6] = (uint8_t)((n) >> 48), (m)[5] = (uint8_t)((n) >> 40), (m)[4] = (uint8_t)((n) >> 32), (m)[3] = (uint8_t)((n) >> 24), (m)[2] = (uint8_t)((n) >> 16), (m)[1] = (uint8_t)((n) >> 8), (m)[0] = (uint8_t)(n))

/* === 类型化数据存取 === */
#define GET_BY_TYPE(p, type)   (*(type *)(p))
#define SET_BY_TYPE(p, v, type) (*(type *)(p) = *(type *)(v))

/* === 数据类型常量（用于协议编解码） === */
#define DATA_TYPE_B     1
#define DATA_TYPE_S8    43
#define DATA_TYPE_U8    32
#define DATA_TYPE_S16   33
#define DATA_TYPE_U16   45
#define DATA_TYPE_S32   2
#define DATA_TYPE_U32   35
#define DATA_TYPE_L64   36
#define DATA_TYPE_UL64  37
#define DATA_TYPE_F32   38
#define DATA_TYPE_D64   39
#define DATA_TYPE_IP    100
#define DATA_TYPE_MAC   101
#define DATA_TYPE_C8    102
#define DATA_TYPE_C32   103
#define DATA_TYPE_C64   104
#define DATA_TYPE_C128  105
#define DATA_TYPE_C1    106
#define DATA_TYPE_STR   107

#ifdef __cplusplus
}
#endif
#endif
