/*********************************************************************
 * @file    platform.c
 * @brief   跨平台系统接口实现（含中断保护/随机数/内存对齐）
 *********************************************************************/
#include "agent_log.h"

#include "platform.h"
#include "type.h"

// -------------------------- 全局变量 --------------------------
static volatile uint32 sys_tick_1us_low = 1u;
static volatile uint32 sys_tick_1us_high = 1u;
static volatile uint32 div_0_1ms_cnt = 0u;
static volatile uint32 div_1ms_cnt = 0u;
static PlatformIrqCallback cb_0_1ms = NULL;
static PlatformIrqCallback cb_1ms = NULL;

// -------------------------- STM32 平台实现 --------------------------
#ifdef STM32
#include "stm32f4xx_hal.h"

// STM32硬件资源句柄
static TIM_HandleTypeDef htim_high_prec;
static RNG_HandleTypeDef hrng;  // 硬件随机数发生器

// -------------------------- STM32 中断保护 --------------------------
uint32 platform_irq_save(void) {
    uint32 primask = __get_PRIMASK();  // 获取当前中断使能状态
    __disable_irq();                   // 关闭全局中断（临界区保护）
    return primask;
}

void platform_irq_restore(uint32 primask) {
    __set_PRIMASK(primask);  // 恢复中断状态（不破坏原有配置）
}


// -------------------------- STM32 内存对齐分配（使用堆+对齐） --------------------------
//void* platform_malloc_aligned(uint32 size, uint32 align) {
//    if (size == 0 || align == 0) return NULL;

//    // 计算额外偏移（确保对齐，额外分配align字节用于存储原始指针）
//    void* raw_ptr = malloc(size + align + sizeof(void*));
//    if (!raw_ptr) return NULL;

//    // 计算对齐后的指针（向上取整到align的整数倍）
//    uintptr_t aligned_addr = ((uintptr_t)raw_ptr + sizeof(void*) + align - 1) & ~(align - 1);
//    void* aligned_ptr = (void*)aligned_addr;

//    // 存储原始指针（用于后续free）
//    *(void**)(aligned_addr - sizeof(void*)) = raw_ptr;

//    return aligned_ptr;
//}

//void platform_free_aligned(void* ptr) {
//    if (!ptr) return;

//    // 取出原始指针并释放
//    void* raw_ptr = *(void**)((uintptr_t)ptr - sizeof(void*));
//    free(raw_ptr);
//}

// -------------------------- STM32 定时器初始化（1μs精度） --------------------------
static bool8 platform_timer_1us_init_stm32(void) {
    __HAL_RCC_TIM2_CLK_ENABLE();  // 使能TIM2时钟
    __HAL_RCC_RNG_CLK_ENABLE();   // 使能RNG时钟（随机数用）

    // TIM2配置（72MHz时钟，1μs计数）
    htim_high_prec.Instance = TIM2;
    htim_high_prec.Init.Prescaler = 71;  // 72MHz / (71+1) = 1MHz
    htim_high_prec.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim_high_prec.Init.Period = 0xFFFF;  // 最大计数周期（65535μs）
    htim_high_prec.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim_high_prec.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    
    if (HAL_TIM_Base_Init(&htim_high_prec) != HAL_OK) {
        return BOOL8_FALSE;
    }

    // 配置TIM2中断（优先级1，确保定时器精度）
    HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(TIM2_IRQn);

    // 启动定时器中断
    if (HAL_TIM_Base_Start_IT(&htim_high_prec) != HAL_OK) {
        return BOOL8_FALSE;
    }

    return BOOL8_TRUE;
}

// STM32 TIM2中断服务函数（1μs计数更新）
void TIM2_IRQHandler(void) {
    if (__HAL_TIM_GET_FLAG(&htim_high_prec, TIM_FLAG_UPDATE) != RESET &&
        __HAL_TIM_GET_IT_SOURCE(&htim_high_prec, TIM_IT_UPDATE) != RESET) {
        
        __HAL_TIM_CLEAR_IT(&htim_high_prec, TIM_IT_UPDATE);  // 清除中断标志

        // 更新1μs计数器（64位，避免溢出）
        sys_tick_1us_low++;
        if (sys_tick_1us_low == 0) {
            sys_tick_1us_high++;
        }

        // 0.1ms回调触发（100次中断=100μs=0.1ms）
        div_0_1ms_cnt++;
        if (div_0_1ms_cnt >= TICK_0_1MS_DIV && cb_0_1ms != NULL) {
            div_0_1ms_cnt = 0;
            cb_0_1ms();
        }

        // 1ms回调触发（1000次中断=1ms）
        div_1ms_cnt++;
        if (div_1ms_cnt >= TICK_1MS_DIV && cb_1ms != NULL) {
            div_1ms_cnt = 0;
            cb_1ms();
        }
    }
}
#endif  // STM32

// -------------------------- Windows 平台实现 --------------------------
#if defined(WIN_AGENT_APP) || defined(AGENT_AT)

#include <windows.h>
// 【修改1】移除BCrypt相关头文件：#include <bcrypt.h>

// Windows资源句柄
static HANDLE h_timer = NULL;
static CRITICAL_SECTION cs_timer;
static CRITICAL_SECTION cs_irq;  // 中断保护用临界区
// 【修改2】移除BCrypt相关句柄：static BCRYPT_ALG_HANDLE h_rng_alg = NULL;
// 【新增1】随机数种子初始化标记（确保仅初始化一次）
static bool8 rand_inited = BOOL8_FALSE;

// 【修改3】移除BCrypt库链接指令：#pragma comment(lib, "bcrypt.lib")

// -------------------------- Windows 中断保护（临界区模拟） --------------------------
uint32 platform_irq_save(void) {
    //EnterCriticalSection(&cs_irq);  // 进入临界区（模拟关闭中断）
    return 0;  // Windows无需返回中断状态，占位
}

void platform_irq_restore(uint32 primask) {
    UNREFERENCED_PARAMETER(primask);
    //LeaveCriticalSection(&cs_irq);  // 离开临界区（模拟恢复中断）
}


// -------------------------- Windows 内存对齐分配（VirtualAlloc） --------------------------
//void* platform_malloc_aligned(uint32 size, uint32 align) {
//    if (size == 0 || align == 0) return NULL;

//    // Windows内存对齐要求：align必须是2的幂，且不超过64KB
//    if ((align & (align - 1)) != 0 || align > 0x10000) {
//        return NULL;
//    }

//    // 使用VirtualAlloc分配对齐内存（自动按页对齐，这里按需求调整）
//    return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
//}

//void platform_free_aligned(void* ptr) {
//    if (ptr) {
//        VirtualFree(ptr, 0, MEM_RELEASE);  // 释放对齐内存
//    }
//}

// -------------------------- Windows 定时器回调 --------------------------
static VOID CALLBACK win_timer_callback(PVOID lpParam, DWORD dwTimerLowValue, DWORD dwTimerHighValue) {
    UNREFERENCED_PARAMETER(lpParam);
    UNREFERENCED_PARAMETER(dwTimerLowValue);
    UNREFERENCED_PARAMETER(dwTimerHighValue);

    EnterCriticalSection(&cs_timer);

    // 更新1μs计数器
    sys_tick_1us_low++;
    if (sys_tick_1us_low == 0) {
        sys_tick_1us_high++;
    }

    // 0.1ms回调触发
    div_0_1ms_cnt++;
    if (div_0_1ms_cnt >= TICK_0_1MS_DIV && cb_0_1ms != NULL) {
        div_0_1ms_cnt = 0;
        cb_0_1ms();
    }

    // 1ms回调触发
    div_1ms_cnt++;
    if (div_1ms_cnt >= TICK_1MS_DIV && cb_1ms != NULL) {
        div_1ms_cnt = 0;
        cb_1ms();
    }

    LeaveCriticalSection(&cs_timer);
}

// -------------------------- Windows 定时器初始化 --------------------------
static bool8 platform_timer_1us_init_windows(void) {
    // 初始化临界区
    InitializeCriticalSection(&cs_timer);
    InitializeCriticalSection(&cs_irq);

    // 创建高精度定时器（1ms周期）
    h_timer = CreateWaitableTimer(NULL, FALSE, NULL);
    if (!h_timer) {
        DeleteCriticalSection(&cs_timer);
        DeleteCriticalSection(&cs_irq);
        return BOOL8_FALSE;
    }

    // 设置定时器周期（1ms，负数值表示100纳秒为单位）
    LARGE_INTEGER liDueTime;
    liDueTime.QuadPart = -10000;  // 10000 * 100纳秒 = 1ms

    if (!SetWaitableTimer(h_timer, &liDueTime, 1, win_timer_callback, NULL, TRUE)) {
        CloseHandle(h_timer);
        h_timer = NULL;
        DeleteCriticalSection(&cs_timer);
        DeleteCriticalSection(&cs_irq);
        return BOOL8_FALSE;
    }

    return BOOL8_TRUE;
}

// Windows毫秒延时（Sleep API）
void platform_delay_ms(uint32 ms) {
    Sleep(ms);
}
#else
/**
 * @brief 非Windows平台毫秒延时（忙等实现，适配嵌入式）
 */

void platform_delay_ms(uint32 ms) {
    uint64 start = platform_get_tick_us();
    uint64 delay_us = (uint64)ms * 1000;  // 毫秒转微秒
    while ((platform_get_tick_us() - start) < delay_us) {
        __NOP();  // 防止编译器优化掉空循环
    }
}
#endif  // WIN_AGENT_APP

// -------------------------- 新增：跨平台大小端转换函数实现 --------------------------
void platform_cpu_to_be32(uint8* out, uint32 value) {
    if (!out) return;
    // 大端序：高位字节在前
    out[0] = (uint8)(value >> 24);
    out[1] = (uint8)(value >> 16);
    out[2] = (uint8)(value >> 8);
    out[3] = (uint8)(value & 0xFF);
}

uint32 platform_be32_to_cpu(const uint8* in) {
    if (!in) return 0;
    // 大端字节数组转主机序：高位字节对应高地址
    return (uint32)((uint32)in[0] << 24) | 
           (uint32)((uint32)in[1] << 16) | 
           (uint32)((uint32)in[2] << 8)  | 
           (uint32)in[3];
}

void platform_cpu_to_be16(uint8* out, uint16 value) {
    if (!out) return;
    // 大端序：高位字节在前
    out[0] = (uint8)(value >> 8);
    out[1] = (uint8)(value & 0xFF);
}

uint16 platform_be16_to_cpu(const uint8* in) {
    if (!in) return 0;
    // 大端字节数组转主机序：高位字节对应高地址
    return (uint16)((uint16)in[0] << 8) | (uint16)in[1];
}

// -------------------------- 通用接口实现 --------------------------
/**
 * @brief 获取1μs精度时间戳（跨平台统一接口）
 */
uint64 platform_get_tick_us(void) {
    uint32 low, high;
    uint32 primask = platform_irq_save();  // 中断保护，避免计数器读取一半被打断

    // 双重读取确保数据一致性（防止高位溢出时低位已重置）
    do {
        high = sys_tick_1us_high;
        low = sys_tick_1us_low;
    } while (high != sys_tick_1us_high);

    platform_irq_restore(primask);
    return ((uint64)high << 32) | low;
}

/**
 * @brief 获取毫秒精度时间戳（跨平台统一接口）
 */
uint32 platform_get_tick_ms(void) {
    return (uint32)(platform_get_tick_us() / 1000);
}

/**
 * @brief 兼容旧接口：获取毫秒精度时间戳（解决LNK2001错误）
 */
uint32 platform_get_tick(void) {
    return platform_get_tick_ms();
}

/**
 * @brief 注册0.1ms周期回调函数
 */
//void platform_register_0_1ms_callback(PlatformIrqCallback cb) {
//    uint32 primask = platform_irq_save();
//    cb_0_1ms = cb;
//    platform_irq_restore(primask);
//}

/**
 * @brief 注册1ms周期回调函数
 */
void platform_register_1ms_callback(PlatformIrqCallback cb) {
    uint32 primask = platform_irq_save();
    cb_1ms = cb;
    platform_irq_restore(primask);
}
// 内存接口（补充基础分配）
//void* platform_malloc(uint32 size) {

//    return malloc(size);  // 未知平台 fallback 到标准库
//}


//void platform_free(void* ptr) {

//    free(ptr);  // 未知平台 fallback 到标准库
//}

/**
 * @brief 平台初始化（统一入口）
 */
void platform_init(void) {
#ifdef STM32
    HAL_Init();  // STM32 HAL库初始化
    (void)platform_timer_1us_init_stm32();
#elif defined(WIN_AGENT_APP)
    (void)platform_timer_1us_init_windows();
#endif
}



#define PLATFORM_RAND 0

/**
 * @brief 获取MAC地址（跨平台统一接口，测试用固定MAC）
 */
//bool8 platform_get_mac(uint8* mac_addr) {
//    if (!mac_addr) return BOOL8_FALSE;

//    // 私有MAC地址范围（02-xx-xx-xx-xx-xx，避免冲突）
//    const uint8 fixed_mac[6] = {0x02, 0x1B, 0x44, 0x55, 0x66, 0x77};
//    memcpy(mac_addr, fixed_mac, 6);
//    return BOOL8_TRUE;
//}

/**
 * @brief 简化接口：默认8字节对齐分配（加密模块常用）
 */
//void* platform_malloc_8aligned(uint32 size) {
//    return platform_malloc_aligned(size, 8);
//}


// -------------------------- 【新增+修改】加密级随机数相关函数 --------------------------
// 128位LFSR状态（静态变量，避免全局污染，周期2^128-1，满足加密级要求）
static uint32_t g_lfsr_state[4] = {0};

/**
 * 【新增辅助函数】128位LFSR生成32位加密级随机数
 * 多项式：x^128 + x^7 + x^2 + x + 1（NIST推荐加密级多项式）
 * 返回：32位无偏倚加密级随机数
 */
static uint32_t _lfsr_gen32(void) {
    // 取LFSR最低位（第0位）作为反馈位
    uint32_t feedback = g_lfsr_state[3] & 1;

    // 128位整体右移1位（高位补低位，循环移位逻辑）
    g_lfsr_state[3] = (g_lfsr_state[3] >> 1) | (g_lfsr_state[2] << 31);
    g_lfsr_state[2] = (g_lfsr_state[2] >> 1) | (g_lfsr_state[1] << 31);
    g_lfsr_state[1] = (g_lfsr_state[1] >> 1) | (g_lfsr_state[0] << 31);
    g_lfsr_state[0] = (g_lfsr_state[0] >> 1);

    // 反馈多项式运算：x^128 + x^7 + x^2 + x + 1（对应掩码0x00000087）
    if (feedback) {
        g_lfsr_state[0] ^= 0x00000087;
    }

    // 返回最高32位（g_lfsr_state[3]），确保输出熵密度最大化
    return g_lfsr_state[3];
}

/**
 * 【修改原有函数】跨平台加密级随机数生成核心（替换rand()为LFSR，满足标准要求）
 * 功能：生成指定长度的加密级随机字节，支持多线程安全，种子熵充足
 * 参数：buf-接收随机字节的缓冲区；len-需要生成的随机字节长度
 * 返回：BOOL8_TRUE-成功；BOOL8_FALSE-失败
 */
static bool8 _platform_rand_c_std(uint8* buf, uint32 len) {
    if (!buf || len == 0) {
        agent_log(AGENT_LOG_ERROR, "_platform_rand_c_std: invalid param (buf=%p, len=%d)", buf, len);
        return BOOL8_FALSE;
    }

    // 临界区保护：避免多线程同时操作LFSR状态，导致随机数错乱
    uint32 primask = platform_irq_save();

    // 种子初始化：仅首次调用执行，增强种子熵（解决原毫秒级时间戳精度低问题）
    static bool8 rand_inited = BOOL8_FALSE;
    if (!rand_inited) {
        uint64_t tick_us[4];  // 存储4次微秒级时间戳，提升种子熵

        // 连续读取4次微秒级时间戳（间隔极短但值不同，通过异或混合最大化熵）
        tick_us[0] = platform_get_tick_us();
        tick_us[1] = platform_get_tick_us();
        tick_us[2] = platform_get_tick_us();
        tick_us[3] = platform_get_tick_us();

        // 初始化128位LFSR状态（高32位与低32位异或，避免时间戳高位无变化导致熵不足）
        g_lfsr_state[0] = (uint32_t)(tick_us[0] >> 32) ^ (uint32_t)tick_us[0];
        g_lfsr_state[1] = (uint32_t)(tick_us[1] >> 32) ^ (uint32_t)tick_us[1];
        g_lfsr_state[2] = (uint32_t)(tick_us[2] >> 32) ^ (uint32_t)tick_us[2];
        g_lfsr_state[3] = (uint32_t)(tick_us[3] >> 32) ^ (uint32_t)tick_us[3];

        // 避免LFSR全0状态（全0时无法生成随机数，强制赋予初始值）
        if (g_lfsr_state[0] == 0 && g_lfsr_state[1] == 0 && 
            g_lfsr_state[2] == 0 && g_lfsr_state[3] == 0) {
            g_lfsr_state[0] = 0x1A2B3C4D;
            g_lfsr_state[1] = 0x5E6F7A8B;
            g_lfsr_state[2] = 0x9C0D1E2F;
            g_lfsr_state[3] = 0x3A4B5C6D;
        }

        rand_inited = BOOL8_TRUE;
        agent_log(AGENT_LOG_DEBUG, "_platform_rand_c_std: crypto-grade RNG init success");
    }

    // 生成加密级随机字节：循环生成32位随机数，拆分后填充缓冲区（无偏倚）
    uint32_t i = 0;
    uint32_t rand32;  // 存储单次LFSR生成的32位随机数
    while (i < len) {
        rand32 = _lfsr_gen32();  // 生成32位加密级随机数

        // 拆分32位随机数为4个8位字节，填充缓冲区（确保每个字节0~255均匀分布）
        for (int j = 0; j < 4 && i < len; j++) {
            buf[i++] = (uint8_t)(rand32 >> (j * 8));
        }
    }

    // 恢复中断状态，退出临界区
    platform_irq_restore(primask);
    agent_log(AGENT_LOG_DEBUG, "_platform_rand_c_std: generate %d bytes crypto-grade random success", len);
    return BOOL8_TRUE;
}

/**
 * 【新增函数】加密级随机数生成接口（供SNMPv3自研算法调用，解决LNK2019错误）
 * 功能：对接加密级随机数内核，为IV生成等加密场景提供安全随机数
 * 参数：buf-接收随机字节的缓冲区；len-需要生成的随机字节长度
 * 返回：BOOL8_TRUE-成功；BOOL8_FALSE-失败
 */
bool8 platform_rand_generate_crypto(uint8* buf, uint32 len) {
    // 直接复用加密级随机数核心逻辑（确保加密场景与通用场景随机数安全级别一致）
    return _platform_rand_c_std(buf, len);
}

 //-------------------------- 【原有保留函数】STM32平台随机数接口（无需修改） --------------------------
//bool8 platform_generate_random(uint8* buf, uint32 len) {
//    // 归一化：通用场景也使用加密级随机数（若需区分，可在此处分支判断）
//    return _platform_rand_c_std(buf, len);
//}

