#include "xysdk_common.h"

static xy_user_info_model *g_xy_user_info=NULL;
static xy_user_vip_info *g_xy_vip_info=NULL;
static xy_temp_token_model *g_xy_temp_token=NULL;
void *xy_common_malloc(uint32_t size)
{
	if(size > 0)
	{
		void *src = (void *)malloc_psram(size);
		if(src == NULL)
			return NULL;
		memset(src,0,size);
		return src;
	}
	return NULL;
}

void xy_common_free(void **src)
{
	if(*src != NULL)
	{
		free_psram(*src);
		*src = NULL;
	}
}


void* xy_common_calloc(uint32_t nblock, uint32_t size)
{
    void *p = calloc(nblock, size);

    return p;
}


void* xy_common_realloc(void* pt, uint32_t size)
{
    void *p = realloc(pt, size);

   
    return p;
}

void xy_set_string_ptr(char **destination, const char *source)
{
    if (*destination == source) {
        return;
    }
    xy_common_free((void**)destination);
    if (source == NULL) {
        *destination = NULL;
    } else {
        *destination = (char*) xy_common_malloc(strlen(source) + 1);
        if (*destination != NULL) {
            strncpy(*destination, source, strlen(source) + 1);
        }
    }
}

char *xy_api_get_timestamp_ms_str(void)
{
	static char *timestamp= NULL;
	if(!timestamp)
	{	
		timestamp = (char *)xy_common_malloc(XY_MAX_STR_LEN_16);
		if(!timestamp)
		{
			return NULL;
		}
	}
	memset(timestamp, 0, XY_MAX_STR_LEN_16);
	sprintf(timestamp, "%d000", xy_api_get_sys_time());
	return timestamp;
}

uint32_t xy_common_get_uid(void)
{
	xy_common_get_user_info();
	if(!g_xy_user_info)
	{
		return 0;
	}

	return g_xy_user_info->user_id;
}
int xy_common_save_temp_token(xy_temp_token_model *temp_token)
{
	if(g_xy_temp_token == NULL)
	{
		g_xy_temp_token = (xy_temp_token_model *)xy_common_malloc(sizeof(xy_temp_token_model));
		if(g_xy_temp_token == NULL)
		{
			return -1;
		}
	}
	memcpy(g_xy_temp_token, temp_token, sizeof(xy_temp_token_model));
	return 0;
}

char *xy_common_get_access_token(void)
{
	int ret = 0;
	if(xy_common_user_is_login())
	{
		if(!g_xy_user_info)
		{
			return NULL;
		}
		//access_token在有效期内
		if((xy_api_get_sys_time() >= g_xy_user_info->access_token_update_time) 
			&& (xy_api_get_sys_time() - g_xy_user_info->access_token_update_time < g_xy_user_info->expires_in - 100))
		{
			return g_xy_user_info->access_token;
		}
		else
		{
			ret = xy_api_http_refresh_access_token();//获取token, 若失败重试一次
			if(ret != 0)
			{
				ret = xy_api_http_refresh_access_token();
				if(ret != 0)
				{
					return NULL;
				}
			}
			return g_xy_user_info->access_token;
		}
	}
	else
	{
		if(g_xy_temp_token != NULL)
		{
			if((xy_api_get_sys_time() >= g_xy_temp_token->temp_token_update_time)
				&& (xy_api_get_sys_time() - g_xy_temp_token->temp_token_update_time < g_xy_temp_token->expires_in - 100))
			{
				return g_xy_temp_token->temp_token;		
			}
		}

		ret = xy_api_http_get_temp_token();
		if(ret != 0)
		{
			ret = xy_api_http_get_temp_token();
			if(ret != 0)
			{
				return NULL;
			}
		}
		return g_xy_temp_token->temp_token;		
	}
}

char *xy_common_get_refresh_token(void)
{
	xy_common_get_user_info();
	if(!g_xy_user_info)
	{
		return NULL;
	}

	if((xy_api_get_sys_time() >= g_xy_user_info->refresh_token_update_time) 
		&& (xy_api_get_sys_time() - g_xy_user_info->refresh_token_update_time < XY_REFRESH_TOKEN_TIMEOUT - 100))
	{
		return g_xy_user_info->refresh_token;//refresh token在有效期内
	}
	else
	{
		return NULL;
	}
}

bool xy_common_user_is_login(void)
{
	xy_common_get_user_info();
	if(g_xy_user_info && strlen(g_xy_user_info->refresh_token))
	{
		return true;
	}
	else
	{
		return false;
	}
}

bool  xy_common_user_is_vip(void)
{
	xy_common_get_user_vip_info(false);
	if(g_xy_vip_info && g_xy_vip_info->is_vip && (xy_api_get_sys_time() < g_xy_vip_info->vip_expires_in))
	{
		return true;
	}
	return false;
}

int xy_common_set_user_vip_info(xy_user_vip_info *vip_info)
{
	extern void h_cpy_usr_vip(int vip);
	h_cpy_usr_vip(vip_info->is_vip);
	if(!vip_info)
	{
		return -1;
	}

	if(g_xy_vip_info == NULL)
	{
		g_xy_vip_info = (xy_user_vip_info *)xy_common_malloc(sizeof(xy_user_vip_info));
		if(g_xy_vip_info == NULL)
		{
			return -1;
		}
	}
	memcpy(g_xy_vip_info, vip_info, sizeof(xy_user_vip_info));

	return 0;
}

xy_user_vip_info *xy_common_get_user_vip_info(bool need_update)
{
	int ret = 0;
	if(!g_xy_vip_info || need_update)
	{
		ret = xy_api_http_user_vip_info();
		if(ret != 0)
		{
			ret = xy_api_http_user_vip_info();
			if(ret != 0)
			{
				return NULL;
			}
		}
		return g_xy_vip_info;
	}
	else
	{
		return g_xy_vip_info;
	}	
}

int xy_common_set_user_info(xy_user_info_model *user_info)
{
	/* extern void h_cpy_usr_info(u8 * name); */
	/* h_cpy_usr_info(user_info->nick_name); */
	char *trackInfo = NULL;
	xm_cJSON *object = NULL;
	int ret=0;

	if(!user_info)
	{
		return -1;
	}

	if(g_xy_user_info == NULL)
	{
		g_xy_user_info = (xy_user_info_model *)xy_common_malloc(sizeof(xy_user_info_model));
		if(g_xy_user_info == NULL)
		{
			return -1;
		}
	}
	memcpy(g_xy_user_info, user_info, sizeof(xy_user_info_model));

	object=xm_cJSON_CreateObject();
	if(object==NULL)
	{
		return -1;
	}

	xm_cJSON_AddNumberToObject(object, "uid", user_info->user_id);
	xm_cJSON_AddNumberToObject(object, "atoken_ts", user_info->access_token_update_time);
	xm_cJSON_AddNumberToObject(object, "ftoken_ts", user_info->refresh_token_update_time);
	xm_cJSON_AddNumberToObject(object, "expires_in", user_info->expires_in);
	xm_cJSON_AddStringToObject(object, "nick_name", user_info->nick_name);
	#ifdef XYSDK_SUPPORT_IMAGE_DOWNLOAD
	xm_cJSON_AddStringToObject(object, "avatar_url", user_info->avatar_url);
	#endif
	xm_cJSON_AddStringToObject(object, "access_token", user_info->access_token);
	xm_cJSON_AddStringToObject(object, "refresh_token", user_info->refresh_token);

    trackInfo = (char *)xm_cJSON_Print(object);
	if(trackInfo)
	{
		ret = xy_api_write_user_data(trackInfo, strlen(trackInfo)); //转成json,保存到文件
	}
	else
	{	
		xm_cJSON_Delete(object);
		return -1;
	}
	xm_cJSON_Delete(object);
	xy_common_free((void **)&trackInfo);
	
	return ret;
}

int xy_common_clear_user_info(void)
{
	if(g_xy_user_info) //清除内存中的登录信息
	{
		memset(g_xy_user_info, 0, sizeof(xy_user_info_model));

		xy_common_free((void **)&g_xy_user_info);
	}

	if(g_xy_vip_info)//清除内存中的vip信息
	{
		memset(g_xy_vip_info, 0, sizeof(xy_user_vip_info));

		xy_common_free((void **)&g_xy_vip_info);
	}

	xy_api_clear_user_data(); //清除缓存中的登录信息
	return 0;
}

static int xy_parse_user_data(char *src_data, xy_user_info_model *resp_data)
{
	int ret = XY_HTTP_SERVER_DATA_ENPTY;
	xm_cJSON *new_obj = NULL;
	xm_cJSON *pSub = NULL;
	if(!src_data || !resp_data)
	{
		return XY_HTTP_PARAM_NULL;
	}

	new_obj = xm_cJSON_Parse(src_data);
	if(!new_obj)
	{
		return XY_HTTP_PARAM_NULL;
	}

	ret = XY_HTTP_DATA_PRASE_ERR;
    pSub = xm_cJSON_GetObjectItem(new_obj, "access_token");
    if(pSub && pSub->valuestring && strlen(pSub->valuestring))
    {
        snprintf(resp_data->access_token, sizeof(resp_data->access_token), "%s", pSub->valuestring);
    }
    else
    {	
        goto exit_user_data;	
    }

	pSub = xm_cJSON_GetObjectItem(new_obj, "refresh_token");
    if(pSub && pSub->valuestring && strlen(pSub->valuestring))
    {
        snprintf(resp_data->refresh_token, sizeof(resp_data->refresh_token), "%s", pSub->valuestring);
    }
    else
    {	
        goto exit_user_data;	
    }

	pSub = xm_cJSON_GetObjectItem(new_obj, "nick_name");
    if(pSub && pSub->valuestring && strlen(pSub->valuestring))
    {
        snprintf(resp_data->nick_name, sizeof(resp_data->nick_name), "%s", pSub->valuestring);
    }
    else
    {	
        snprintf(resp_data->nick_name, sizeof(resp_data->nick_name), "%s", "未知");	
    }
	#ifdef XYSDK_SUPPORT_IMAGE_DOWNLOAD
	pSub = xm_cJSON_GetObjectItem(new_obj, "avatar_url");
    if(pSub && pSub->valuestring && strlen(pSub->valuestring))
    {
        snprintf(resp_data->avatar_url, sizeof(resp_data->avatar_url), "%s", pSub->valuestring);
    }
	#endif

	pSub = xm_cJSON_GetObjectItem(new_obj, "uid");
    if(pSub && pSub->valueint != 0)
    {
        resp_data->user_id = pSub->valueint;
    }

	pSub = xm_cJSON_GetObjectItem(new_obj, "expires_in");
    if(pSub && pSub->valueint != 0)
    {
        resp_data->expires_in = pSub->valueint;
    }

	pSub = xm_cJSON_GetObjectItem(new_obj, "atoken_ts");
    if(pSub && pSub->valueint != 0)
    {
        resp_data->access_token_update_time = pSub->valueint;
    }

	pSub = xm_cJSON_GetObjectItem(new_obj, "ftoken_ts");
    if(pSub && pSub->valueint != 0)
    {
        resp_data->refresh_token_update_time = pSub->valueint;
    }
    XY_LOG_I("resp_data->access_token: %s", resp_data->access_token);
	ret = XY_HTTP_OK;
	
exit_user_data:
	if (new_obj) 
	{
        xm_cJSON_Delete(new_obj);
        new_obj = NULL;
    }

	return ret;
}
xy_user_info_model *xy_common_get_user_info(void)
{
	uint16_t user_info_len = sizeof(xy_user_info_model)+256;
	int ret = 0;

	if(g_xy_user_info)
	{
		return g_xy_user_info;
	}
	else
	{
		char *user_info = (char *)xy_common_malloc(user_info_len);
		if(!user_info)
		{
			return NULL;
		}

		ret = xy_api_read_user_data(user_info, user_info_len);
		if(ret < 0)
		{
			XY_LOG_E("read user data fail ret: %d",ret);
			xy_common_free((void **)&user_info);
			return NULL;
		}

		if(g_xy_user_info == NULL)
		{
			g_xy_user_info = (xy_user_info_model *)xy_common_malloc(sizeof(xy_user_info_model));
			if(g_xy_user_info == NULL)
			{
				XY_LOG_W("malloc fail");
				xy_common_free((void **)&user_info);
				return NULL;
			}
		}

		if(xy_parse_user_data(user_info, g_xy_user_info) == 0)
		{
			xy_common_free((void **)&user_info);
			return g_xy_user_info;
		}
		else
		{
			XY_LOG_W("parse user data fail");
			xy_common_free((void **)&user_info);
			xy_common_free((void **)&g_xy_user_info);
			return NULL;
		}
	}
}