#include "timer.h"
#include "uv.h"
#include "pthread.h"
#include "bmser_log.h"


typedef struct data_ptr_s{
    uv_timer_cb cb;
    void* arg;
};

typedef struct {
    uv_loop_t* loop;    
    uv_timer_t uv_timer;
    pthread_t thread_id;
    struct data_ptr_s pri;
}single_timer_inner_t;

typedef struct bs_timer_pri_s bs_timer_pri_s;
struct bs_timer_pri_s{
  int timeout_ms;
  int repeat; 
  int active;
  void *arg;
  bs_timer_cb timer_cb;
};

struct bs_timer_s {
  int unused;
  void *ctmer;
  void *reseved;
  bs_timer_pri_s pri; 
};


static void _timer_cb(uv_timer_t* handle)
{
    struct data_ptr_s* ptr = handle->data;
    ptr->cb(ptr->arg);
}

static void __timer_single(void *arg)
{   
    bs_timer_t timer = (bs_timer_t)arg;
    single_timer_inner_t* __timer = timer->ctmer;
    uv_loop_t* loop = __timer->loop;
    uv_run(loop, UV_RUN_DEFAULT); 
    pthread_exit(NULL);
    return ;
}
/**
 * @brief   单实例的定时器
 *          每个定时器新开启一个新的线程；
 *          当定时处理任务中有阻塞操作时；或者定时器处理任务需要临时添加与删除的情况下使用； 
 *          ！！！！定时器不再使用时，请使用close操作!!!!!!!!
 * 
 * @param timeout_cb      回调函数
 * @param timeout         超时时间 
 * @param repeat          是否重复操作
 * @param arg             参数
 * @return        返回的单实例定时器; NULL: 失败；
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
bs_timer_t  timer_single_init(bs_timer_cb timeout_cb, uint32_t timeout, uint32_t repeat, void *arg)
{   
    int ret = 0;
    bs_timer_t timer = NULL;
    single_timer_inner_t *_timer = NULL;
    uv_loop_t *loop = NULL;
    
    timer = (bs_timer_t )malloc(sizeof(bs_timer_t));
    if(timer == NULL){
        return NULL;
    }
    loop = uv_loop_new();
    uv_loop_init(loop);
    _timer = malloc(sizeof(single_timer_inner_t));
    timer->ctmer = _timer;
    _timer->loop = loop;
    uv_timer_t* uv_timer = &_timer->uv_timer;
    _timer->pri.arg = arg;
    _timer->pri.cb = timeout_cb;
    _timer->uv_timer.data = &_timer->pri;
    struct data_ptr_s* pri = &_timer->pri;
    pri->arg = arg;
    pri->cb = timeout_cb;
    timer->unused = 0x12345678;
    uv_timer_init(loop, uv_timer);
    uv_timer_start(uv_timer, _timer_cb, timeout, repeat);
    if(0 != pthread_create(&_timer->thread_id, NULL,__timer_single , timer)){
        return -1;
    }
    pthread_detach(_timer->thread_id);
    return timer;
}

/**
 * @brief 暂停定时器，可以根据期望后面可以任然开启
 * 
 * @param timer_single 
 * @return int 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
int timer_single_stop(bs_timer_t timer_single)
{   
    single_timer_inner_t* _timer = timer_single->ctmer;
    uv_loop_t *loop = _timer->loop;
    uv_timer_stop(&_timer->uv_timer);

    return 0;
}

/**
 * @brief 启动定时器
 * 
 * @param timer_single 
 * @return int 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
int timer_single_start(bs_timer_t timer_single)
{  
    single_timer_inner_t* _timer = timer_single->ctmer;
    uv_loop_t* loop = _timer->loop;
    uv_timer_again(&_timer->uv_timer);

    return 0;
}

/**
 * @brief 删除定时器
 * 
 * @param timer_single 
 * @return int     <0 失败 0:正常
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
int timer_single_close(bs_timer_t timer_single)
{
    int ret = 0;
    single_timer_inner_t* _timer = timer_single->ctmer;
    uv_loop_t* loop = _timer->loop;
    uv_stop(&_timer->uv_timer);
    pthread_cancel(_timer->thread_id);

    free(timer_single->ctmer);
    free(timer_single);
    return ret;
}

#define MAX_TIMER_LIMIT 100
typedef struct _timer_list_pri_s timer_list_pri_s;
struct _timer_list_pri_s{
  int fd;           
  int used_flag;
  int timeout_ms;
  int repeat; 
  int idx;
  void *arg;
  bs_timer_cb timer_cb;
};

struct timer_list_s {
    int epollfd;
    int max_sw_num;
    int used_num;
    void* lock;
   timer_list_pri_s* sw_array[MAX_TIMER_LIMIT];
};
static int __timer_list_thread(timer_list_t tmr);
static int __timer_list_close(timer_list_t tmr);

typedef struct {
    uv_loop_t *loop;
    uv_timer_t uv_timer[50];
    pthread_t thread_id;
    struct data_ptr_s pri[50];
}list_timer_inner_t;

__list_callback(void* arg)
{
    printf("alive \n");
}

/**
 * @brief  申请一个定时器，可以对该定时器扩展硬件定时功能，CPU消耗较小,一个timer_list回调在一个线程中
           使用timer fd 实现，消耗了较多系统资源 
           !!!!!使用完成后必须timer_list_close回收资源!!!!
 * 
 * 
 * 
 * @param sw_tmr_num       包含的软件定时器个数
 * @return timer_list_t    软件定时器的列表指针
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
timer_list_t timer_list_create(int sw_tmr_num)
{
    int ret = 0;
    uv_loop_t *loop = NULL;
    loop = uv_loop_new();
    uv_loop_init(loop);

    timer_list_t tmr_sw = NULL;
    tmr_sw = malloc(sizeof(timer_list_t));
    if(tmr_sw == NULL){
        dy_syslog(LOG_ERR,"timer sw error");
        goto clean_up;
    }
    memset(tmr_sw, 0x00, sizeof(timer_list_t));
    list_timer_inner_t *__timer = malloc(sizeof(list_timer_inner_t));
    tmr_sw->lock = __timer;
    __timer->loop = loop;
    tmr_sw->max_sw_num = sw_tmr_num > 50 ? 50: sw_tmr_num;
    tmr_sw->used_num = 0;
    timer_list_add_one(tmr_sw, __list_callback, 1000,1, tmr_sw);
    if(0 != pthread_create(&__timer->thread_id, NULL,__timer_list_thread , tmr_sw)){
        goto clean_up;
    }
    pthread_detach(__timer->thread_id);
    return tmr_sw;
clean_up:
    uv_loop_close(loop);
    return NULL;
}

static int __timer_list_thread(timer_list_t  tmr)
{   
    list_timer_inner_t* __timer = tmr->lock;
    uv_loop_t *loop = __timer->loop;
    while(1)
        uv_run(loop, UV_RUN_DEFAULT);
    pthread_exit(NULL);
}
/**
 * @brief  向定时器列表中添加一个定时器任务
 * 
 * @param tmr         定时器列表
 * @param timeout_cb  回调函数
 * @param timeout     超时时间
 * @param repeat      是否重复
 * @param arg         用户参数
 * @return int        > 0 返回当前软件定时器的id;
 *                    其它错误
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
int timer_list_add_one(timer_list_t tmr, bs_timer_cb timeout_cb, uint32_t timeout, uint32_t repeat, void *arg)
{   
    int idx = 0;
    if(tmr == NULL){
        return -1;
    }
    list_timer_inner_t* __timer = tmr->lock;
    uv_loop_t* loop = __timer->loop;
    idx = tmr->used_num;
    uv_timer_t* timer = &__timer->uv_timer[idx];
    struct data_ptr_s *pri = &__timer->pri[idx];
    uv_timer_init(loop, timer);
    pri->arg = arg;
    pri->cb = timeout_cb;
    timer->data = pri;
    uv_timer_start(timer, _timer_cb,repeat,timeout );
    tmr->used_num++;
    return idx;
}

/**
 * @brief           暂停一个软件定时器
 * 
 * @param tmr       定时器列表
 * @param id        定时器ID
 * @return int      0:成功
 *                  非0:失败
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
int timer_list_stop_one(timer_list_t tmr, int idx)
{
    if(tmr == NULL){
        return -1;
    }
    list_timer_inner_t* __timer = tmr->lock;
    uv_loop_t* loop = __timer->loop;
    uv_timer_t* timer = &__timer->uv_timer[idx];
    
    uv_timer_stop(timer);
    return 0;
}

/**
 * @brief           删除一个定时器
 * 
 * @param tmr       定时器列表
 * @param id        定时器ID
 * @return int 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
int timer_list_remove_one(timer_list_t tmr, int idx)
{
    if(tmr == NULL){
        return -1;
    }
    list_timer_inner_t* __timer = tmr->lock;
    uv_loop_t* loop = __timer->loop;
    uv_timer_t* timer = &__timer->uv_timer[idx];

    uv_timer_stop(timer);
    return 0;
}


/**
 * @brief           启动一个定时器
 * 
 * @param tmr       定时器列表
 * @param id        定时器ID
 * @return int      0:成功
 *                  非0:失败  
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
int timer_list_start_one(timer_list_t tmr, int idx)
{
    list_timer_inner_t* __timer = tmr->lock;
    uv_loop_t* loop = __timer->loop;
    uv_timer_t* timer = &__timer->uv_timer[idx];

    uv_timer_again(timer);
    return 0;
}


/**
 * @brief           !!!!!!关闭一个定时器列表!!!!!!!
 *                  使用定时器的进程退出前必须要调用，否则会导致定时器fd会不断创建
 * 
 * @param tmr 
 * @return int      0:成功
 *                  非0:失败  
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11 <td>1.0     <td>dfs     <td>内容
 * </table>
 */
int timer_list_close(timer_list_t tmr)
{
    if(tmr == NULL){
        return 0;
    }
    list_timer_inner_t* __timer = tmr->lock;
    uv_loop_t* loop = __timer->loop;

    uv_stop(loop);
    return 0;
}









