#include "log_module.h"
#include "pthread.h"
#include "string.h"
#include <stdlib.h>
#include "dy_utils/hash_intptr.h"
#include "../common.h"
#include <stdio.h>
#include "lnxall_list.h"
static pthread_rwlock_t list_rwlock = PTHREAD_RWLOCK_INITIALIZER;
static struct list_head wirte_list;
static int current_list_num = 0;//存储当前的队列的数据数量 不用一直遍历
static struct hash_intptr *log_hash;
static int current_fd = -1;

static pthread_mutex_t g_hash_lock = PTHREAD_MUTEX_INITIALIZER;

static inline void log_free(void *p)
{
    if (p!=NULL)
    {
        free(p);
    }
}

int log_module_server_init()
{
    INIT_LIST_HEAD(&wirte_list);
    return 0;
}

int period_state_clean(LOG_CODE_LIST log_code) //清除已经禁止的周期上报
{
    int locked;

    
    int *saved=NULL;

    locked = pthread_mutex_lock(&g_hash_lock);
    if (locked != 0) {
        fprintf(stderr, "Error, failed to lock for has failed: %d\n", locked);
        fflush(stderr);
    }
    if (hash_intptr_findptr(log_hash,&log_code,sizeof(int), (void **)&saved) < 0)
    {
        if (locked == 0)
            pthread_mutex_unlock(&g_hash_lock);
        return 0;
    }
    else
    {
        log_free(saved);
        hash_intptr_remove(&log_hash,&log_code,sizeof(log_code));//删除
    }

    if (locked == 0)
        pthread_mutex_unlock(&g_hash_lock);
    return 0;
}
/**
 * LOG_MODE 是LOG_MODE_PERIOD
 * 
*/
int server_add_new_log(LOG_CODE_LIST log_code,char *no,LOG_MODE mode,int value,char *add)
{
    int locked;
    int *saved=NULL;

    locked = pthread_mutex_lock(&g_hash_lock);
    if (locked != 0) {
        fprintf(stderr, "Error, failed to lock for has failed: %d\n", locked);
        fflush(stderr);
    }

    if (hash_intptr_findptr(log_hash,&log_code,sizeof(int), (void **)&saved) < 0)
    {
        if (mode == LOG_MODE_PERIOD)
        {
            saved  = calloc(1,sizeof(int));
            *saved = value;
            int ret = hash_intptr_addptr(&log_hash,&log_code,sizeof(log_code),saved);
            if (ret < 0)
            {
                printf("hash_intptr_addptr err!\n");
            }
        }
    }
    else
    { 
        if (*saved!=value)
        {
            log_free(saved);
            hash_intptr_remove(&log_hash,&log_code,sizeof(log_code));//删除
        }
        else
        {
            if (mode == LOG_MODE_PERIOD)
            {
                if (locked == 0)
                    pthread_mutex_unlock(&g_hash_lock);
                return 0; //重复添加了
            }
        }
    }

    if (locked == 0)
        pthread_mutex_unlock(&g_hash_lock);

    LOG_MODULE *log_module = calloc(1,sizeof(LOG_MODULE));
    log_module->log_info = calloc(1,sizeof(ONE_LOG_INFO));
    log_module->log_info->log_code = log_code;
    log_module->log_info->value = value;
    log_module->log_info->raiseTime = time(NULL);
    if (add!=NULL&&strlen(add))
    {
        log_module->log_info->add = strdup(add);
    }
    if (no!=NULL&&strlen(no))
    {
        log_module->log_info->no = strdup(no);
    }
    // printf("add new log code %d\n",log_code);
    pthread_rwlock_wrlock(&list_rwlock);
    list_add_tail(&log_module->list, &wirte_list);
    current_list_num++;
    if (current_list_num>MAX_LIST_NUM) //超过最大数量删除
    {
        LOG_MODULE *log_module_t = (LOG_MODULE *)wirte_list.next;
        list_del(wirte_list.next);
        current_list_num--;
        pthread_rwlock_unlock(&list_rwlock);
        log_free(log_module_t->log_info->add);
        log_free(log_module_t->log_info->no);
        log_free(log_module_t->log_info);
        log_free(log_module_t);
    } else {
        pthread_rwlock_unlock(&list_rwlock);
    }
    return 0;
}

int log_module_client_init()
{
    if (current_fd>=TRIGGER_LIST_MAX)
    {
        return -1;
    }
    current_fd++;
    return current_fd;
}

int get_all_log_num()
{
    return current_list_num;
}

int client_get_log_with_offset(int fd,int start_num,int num,get_log_cb get_log_cb_t,void *context)//fd大于0 获取未被当前客户端标记的log中指定数量条目并标记 fd<0则获取当前所有的log且不标记任何读取过标志
{
    LOG_MODULE *log_module;
    int current_num = 0;
    int get_num = 0;
    if (num < 0)
    {
        num = MAX_LIST_NUM+1;
    }
    pthread_rwlock_wrlock(&list_rwlock);
    list_for_each_entry(log_module, &wirte_list, list)
    {
        if (log_module == NULL)
        {
            continue;
        }
        current_num++;
        
        if (fd<0)
        {
            if (current_num<start_num) 
                continue;
            else if (current_num>=(start_num+num)) 
                break;
            get_log_cb_t(log_module->log_info,context);
            get_num++;
        }
        else
        {
            if (current_num<start_num) 
                continue;
            if (log_module->log_info->trigger_list[fd]!=1)
            {
                get_log_cb_t(log_module->log_info,context);
                get_num++;
                log_module->log_info->trigger_list[fd]=1;
                if (get_num>=num) 
                break;
            }
        }   
    }
    pthread_rwlock_unlock(&list_rwlock);
    return get_num;
}
