#include <string.h>
#include <stdlib.h>
#include "klist.h"
#include "kk_log.h"
#include "kk_tsl_common.h"
#include "kk_dm_mng.h"


typedef struct {

    void *mutex;
	void *hearbeat_thread;
    int hearbeat_thread_running;	
    //struct list_head dev_list;	
} kk_heartbeat_ctx_t;
#if 0
typedef struct {
    unsigned int timerstamp;
    char deviceCode[DEVICE_CODE_MAXLEN];
    struct list_head linked_list;
} kk_dev_heartbeat_node_t;
static int _kk_add_heartbeat_node(const char* deviceCode,unsigned int timestamp)
{
    kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
    kk_dev_heartbeat_node_t *node = NULL;

    node = malloc(sizeof(kk_dev_heartbeat_node_t));
    if (node == NULL) {
        return MEMORY_NOT_ENOUGH;
    }
	_kk_heartbeat_lock();
	memset(node,0x0,sizeof(kk_dev_heartbeat_node_t));
	memcpy(node->deviceCode,deviceCode,strlen(deviceCode));
	node->timerstamp = timestamp;
    INIT_LIST_HEAD(&node->linked_list);
    list_add_tail(&node->linked_list, &ctx->dev_list);
	_kk_heartbeat_unlock();
	return SUCCESS_RETURN;



}
int kk_heartbeat_update_time(const char deviceCode[DEVICE_CODE_MAXLEN],unsigned int timestamp)
{
    kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
    kk_dev_heartbeat_node_t *search_node = NULL;

	_kk_heartbeat_lock();
    list_for_each_entry(search_node, &ctx->dev_list, linked_list, kk_dev_heartbeat_node_t) {
        if ( (strlen(search_node->deviceCode) == strlen(deviceCode)) &&
            (memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
            search_node->timerstamp = timestamp;
			_kk_heartbeat_unlock();
            return SUCCESS_RETURN;
        }
    }
	_kk_add_heartbeat_node(deviceCode,timestamp);
	_kk_heartbeat_unlock();
	return FAIL_RETURN;

}

#endif

static kk_heartbeat_ctx_t s_kk_heartbeat_ctx = {0};
static kk_heartbeat_ctx_t *_kk_heartbeat_get_ctx(void)
{
    return &s_kk_heartbeat_ctx;
}
static void _kk_heartbeat_lock(void)
{
    kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
    if (ctx->mutex) {
        HAL_MutexLock(ctx->mutex);
    }
}

static void _kk_heartbeat_unlock(void)
{
    kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
    if (ctx->mutex) {
        HAL_MutexUnlock(ctx->mutex);
    }
}
uint64_t s_start_time = 0;

void *kk_heartbeat_yield(void *args)
{
    kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
	uint64_t current_time = 0;
    dm_mgr_dev_node_t *search_node = NULL;	
    while (ctx->hearbeat_thread_running) {
		current_time = HAL_UptimeMs() - s_start_time;
		_kk_heartbeat_lock();
		dm_mgr_check_heartbeat_timeout(current_time);
		_kk_heartbeat_unlock();
		sleep(30);
    }
    return NULL;
}

int kk_heartbeat_init(void)
{
	int res = 0;
    kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
    /* Create Mutex */
    ctx->mutex = HAL_MutexCreate();
    if (ctx->mutex == NULL) {
        return FAIL_RETURN;
    }
    /* Init Device Id*/
    ctx->hearbeat_thread_running = 1;
	s_start_time = HAL_UptimeMs();

	res = pthread_create(&ctx->hearbeat_thread, NULL, kk_heartbeat_yield, NULL);
	if (res < 0) {
		ERROR_PRINT("HAL_ThreadCreate ota Failed\n");
		//IOT_Linkkit_Close(mid_ctx->master_devid);
		return FAIL_RETURN;
	}
	return SUCCESS_RETURN;

    /* Init Device List */
   // INIT_LIST_HEAD(&ctx->dev_list);

}


