#include "battery_manager.h"
#include "battery_interface.h"

#include "mem_section.h"

#define BATTERY_MGR_SLEEP_THRESHOLD     15               /* 睡眠阈值，与 check_and_notify 保持一致 */
#define BATTERY_MGR_ALARM_THRESHOLD     20               /* 报警阈值，与 check_and_notify 保持一致 */

/* 将原始 SOC 线性映射到 [0,100] 的宏 */
#define BATTERY_MGR_MAP_SOC_TO_USER(raw_soc, sleep_thr) \
    (((raw_soc) > (sleep_thr)) ? (((raw_soc) - (sleep_thr)) * 100 / (100 - (sleep_thr))) : 0)
 
/* 将用户层看到的电量百分比反向映射回原始 SOC */
#define BATTERY_MGR_USER_TO_SOC(user_soc) \
    (((user_soc) == 0) ? 0 : ((user_soc) * (100 - BATTERY_MGR_SLEEP_THRESHOLD) / 100) + BATTERY_MGR_SLEEP_THRESHOLD)

#define BATTERY_MGR_THREAD_STACK_SIZE       (2 * 1024)  /**< 电池管理线程栈大小 */
#define BATTERY_MGR_THREAD_PRIORITY         (20)        /**< 电池管理线程优先级 */
#define BATTERY_MGR_THREAD_TIMESLICE        (10)        /**< 电池管理线程时间片 */



/* 使用特定的内存段宏，如果系统有要求的话。这里参考 bq27z561_manager.c 的做法 */
#if defined(__CC_ARM) || defined(__CLANG_ARM)
    L2_RET_BSS_SECT_BEGIN(g_battery_thread_stack)
    static uint32_t g_battery_mgr_stack[BATTERY_MGR_THREAD_STACK_SIZE / sizeof(uint32_t)];
    L2_RET_BSS_SECT_END
#else
    static uint32_t g_battery_mgr_stack[BATTERY_MGR_THREAD_STACK_SIZE / sizeof(uint32_t)];
#endif



typedef struct {
    bool initialized;           /**< 是否初始化 */

    const battery_drv_ops_t *driver;
    
    battery_mgr_info_t current_info;
    battery_drv_raw_data_t  raw_data;

    battery_mgr_callback_t observer;
    
    struct rt_thread thread;
} battery_mgr_t;

static battery_mgr_t g_battery_mgr;

static battery_mgr_status_t battery_mgr_get_status(const battery_drv_raw_data_t *raw_data)
{
    if (raw_data->soc >= 100) {
        return BATTERY_MGR_STATUS_FULL;
    }
    if (raw_data->current > 0) {
        return BATTERY_MGR_STATUS_CHARGING;
    }
    if (raw_data->current < 0) {
        return BATTERY_MGR_STATUS_DISCHARGING;
    }
    return BATTERY_MGR_STATUS_UNKNOWN;
}

/*
 * @brief 初始化电池管理器
 * @details 该函数初始化电池管理器，创建定时器并启动它。
 * @return rt_err_t 返回初始化状态，RT_EOK 表示成功，其他值表示失败
 */
rt_err_t battery_mgr_init(void)
{
    battery_mgr_t *mgr = &g_battery_mgr;

    if (mgr->initialized) {
        rt_kprintf("func: %s, Battery manager already initialized\n", __func__);
        return -RT_ERROR;
    }

    mgr->driver = battery_drv_get_ops();

    if (mgr->driver && mgr->driver->init) {
        mgr->driver->init();
    }

    rt_err_t err = rt_thread_init(&mgr->thread,
                                "battery_mgr_thread",   
                                battery_mgr_thread_entry, 
                                mgr, 
                                g_battery_mgr_stack,
                                BATTERY_MGR_THREAD_STACK_SIZE, 
                                BATTERY_MGR_THREAD_PRIORITY, 
                                BATTERY_MGR_THREAD_TIMESLICE);
    if (err != RT_EOK) {
        rt_kprintf("func: %s, Failed to create thread\n", __func__);
        return -RT_ERROR; 
    }

    rt_thread_startup(&mgr->thread);

    mgr->initialized = true;

    rt_kprintf("func: %s, Battery manager initialized successfully.\r\n", __func__);

    return RT_EOK;
}
                                 
/*
 * @brief 电池管理器线程入口函数
 * @details 该函数在电池管理器线程中运行，主要负责处理电池状态更新和通知。
 * @param parameter 线程参数，通常是电池管理器实例指针
 */
static void battery_mgr_thread_entry(void *parameter)
{
    battery_mgr_t *mgr = (battery_mgr_t *)parameter;

    while (1) {
        battery_drv_raw_data_t raw_data = {0};
        rt_kprintf("func: %s, tick: %d.\r\n", __func__, rt_tick_get());
        /* 1. 从驱动层获取数据 */
        if (mgr->driver && mgr->driver->read) {
            if (mgr->driver->read(&raw_data) != RT_EOK) {
                rt_thread_delay(rt_tick_from_millisecond(1000));
                continue;
            }
        } else {
            rt_thread_delay(rt_tick_from_millisecond(1000));
            continue;
        }

        rt_kprintf("func: %s, raw_data: %d, %d, %d, %d.\r\n", __func__, raw_data.soc, raw_data.voltage, raw_data.current,raw_data.remaining_capacity);
        /* 2. 解析驱动层数据，将原始 SOC 重新映射到 [0,100] */
        mgr->raw_data = raw_data;
        mgr->current_info.soc = BATTERY_MGR_MAP_SOC_TO_USER(raw_data.soc, BATTERY_MGR_SLEEP_THRESHOLD);
        mgr->current_info.status = battery_mgr_get_status(&raw_data);

        if (mgr->current_info.status == BATTERY_MGR_STATUS_CHARGING) {
            mgr->current_info.is_sleep = false;
            mgr->current_info.is_low_power = false;
        }

        /* 3. 若电池电量低于休眠阈值，电池处于放电状态，未进入睡眠状态，则将触发休眠回调 */
        if (raw_data.soc <= BATTERY_MGR_SLEEP_THRESHOLD) {
            if (mgr->current_info.status == BATTERY_MGR_STATUS_DISCHARGING) {
                if (!mgr->current_info.is_sleep) {
                    mgr->current_info.is_sleep = true;
                    if (mgr->observer) {
                        mgr->observer(BATTERY_MGR_EVENT_ENTRY_SLEEP, &mgr->current_info);
                    }
                }
                rt_thread_delay(rt_tick_from_millisecond(1000));
                continue;
            }
        }

        /* 4. 若电池电量低于报警阈值，电池处于放电状态，未触发报警，则将触发报警回调（电池电量为用户层电量） */
        if (raw_data.soc <= BATTERY_MGR_USER_TO_SOC(BATTERY_MGR_ALARM_THRESHOLD)) {
            if (mgr->current_info.status == BATTERY_MGR_STATUS_DISCHARGING) {
                if (!mgr->current_info.is_low_power) {
                    mgr->current_info.is_low_power = true;
                    if (mgr->observer) {
                        mgr->observer(BATTERY_MGR_EVENT_LOW_POWER, &mgr->current_info);
                    }
                }
            }
        } else if (mgr->current_info.is_low_power) {
            mgr->current_info.is_low_power = false;
        }
        if (mgr->observer) {
            mgr->observer(BATTERY_MGR_EVENT_UPDATE, &mgr->current_info);
        }
        
        rt_thread_delay(rt_tick_from_millisecond(1000));
    }
}

/*
 * @brief 注册电池管理器事件回调函数
 * @details 该函数用于注册电池管理器事件回调函数，当电池状态发生变化时，会调用该回调函数。
 * @param observer 电池管理器事件回调函数指针
 * @return rt_err_t 返回注册状态，RT_EOK 表示成功，其他值表示失败   
*/
rt_err_t battery_mgr_register_observer(battery_mgr_callback_t observer)
{
    if (!observer) {
        rt_kprintf("func: %s, Invalid observer function pointer\n", __func__);
        return -RT_ERROR;
    }

    g_battery_mgr.observer = observer;

    rt_kprintf("func: %s, Observer registered successfully\n", __func__);

    return RT_EOK;
}
