#include <time.h>
#include "mqtt_verify.h"
#include "mqtt_aes.h"
#include "common.h"
#include "device_identity.h"
#include "mqtt_init.h"
#include "mylog.h"
#include "http_config_mqtt.h"

/*TRUE为打开验证，FALSE为关闭验证*/
bool VERIFIED_MODE=FALSE;

static bool s_service_verify=TRUE;//验证判断

int g_verify_count =6000;//判断是否有一分钟

static char s_only_id_middle[11];

static char s_secret_key[1024];//存储上一次的topic

static bool s_secret_key_index = TRUE;//用于判断是否对比topic

/* topic 不同时发后端验证，失败可重试，超过 3 次不通过则判定该 topic 不通过 */
static char s_pending_verify_token[1024];
static char s_last_seen_token[1024]; /* 用于判断token是否变化（首次启动默认全0） */
static int s_verify_retry_count = 0;
static time_t s_verify_retry_after_time = 0; /* 允许发起重试的时间戳，0 表示无待重试 */
#define VERIFY_RETRY_MAX 3
#define VERIFY_RETRY_INTERVAL_SEC 1

/* 启动时向后端查询是否开启验证(3013/2013) */
#define VERIFY_OPEN_QUERY_MAX 3
#define VERIFY_OPEN_QUERY_INTERVAL_SEC 3

static bool s_verify_open_got_reply = false;   /* 已收到后端2013 */
static bool s_verify_open_query_gave_up = false; /* 3次未收到，已放弃 */
static int s_verify_open_send_count = 0;       /* 已发送3013次数 */
static time_t s_verify_open_last_send_time = 0;

int g_verify_index =0;//判断是否验证成功
pthread_mutex_t g_verify_mutex = PTHREAD_MUTEX_INITIALIZER;//线程锁

char *generate_random_id() {

    char *id_buffer=malloc(11);
    // 1. 定义字符池：包含所有小写字母、大写字母和数字
    const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    const int charset_size = sizeof(charset) - 1; // 减去末尾的 '\0'

    // 2. 循环生成每个字符
    for (int i = 0; i < 10; ++i) {
        // 从字符池中随机选择一个字符
        int key = rand() % charset_size;
        id_buffer[i] = charset[key];
    }

    // 3. 在字符串末尾添加空字符终止符
    id_buffer[10] = '\0';
    return id_buffer;
}

//发送用户获取jwt给服务端验证
int send_jwtser(const char *token){

    cJSON *root = cJSON_CreateObject();
    cJSON *body = cJSON_CreateObject();
    cJSON *head = cJSON_CreateObject();

    char *only_Id =generate_random_id();

    my_zlog_debug("%s",only_Id);

    strcpy(s_only_id_middle,only_Id);

    cJSON_AddStringToObject(body, "data", token);//为0成功

     cJSON_AddStringToObject(body, "only_id", only_Id);

    cJSON_AddNumberToObject(head, "message_type",3006);

    cJSON_AddItemToObject(root, "body", body);
    cJSON_AddItemToObject(root, "head",head);

    char *payload = cJSON_PrintUnformatted(root);
    my_zlog_debug("%s",payload);

    mqtt_publish_to_all(mqtt_topic_pure_number(), payload, 0);
    
    free(payload);
    free(only_Id);
    cJSON_Delete(root);
}

//jwt验证函数
int receive_jwt(cJSON *body) {

    char *token=NULL;
    char *token_time=NULL;
    
    cJSON *json_token = cJSON_GetObjectItem(body, "token");
    cJSON *json_token_time = cJSON_GetObjectItem(body, "token_time");
    if(json_token == NULL || json_token_time==NULL) {
        my_zlog_warn("JWT验证失败: token或token_time字段缺失, token=%s",
                     (json_token && cJSON_IsString(json_token) && json_token->valuestring) ? json_token->valuestring : "<null>");
        g_verify_index=1;
        return 1;
    }

    token=json_token->valuestring;
    token_time=json_token_time->valuestring;

    /* 空字符串视为无效，不发给后端 */
    if (token == NULL || token[0] == '\0' || token_time == NULL || token_time[0] == '\0') {
        my_zlog_error("JWT验证失败: token或token_time为空, token=%s",
                      (token && token[0] != '\0') ? token : "<empty>");
        g_verify_index = 1;
        return 1;
    }

    /* 有待重试且已过 1s：等有消息进来时再发重试，不阻塞 */
    if (s_verify_retry_count > 0 && s_verify_retry_count < VERIFY_RETRY_MAX
        && s_verify_retry_after_time > 0 && time(NULL) >= s_verify_retry_after_time) {
        s_verify_retry_after_time = 0;
        send_jwtser(s_pending_verify_token);
        my_zlog_info("距上次失败已过%d秒，发起第%d次重试验证, token=%s",
                       VERIFY_RETRY_INTERVAL_SEC, s_verify_retry_count + 1, s_pending_verify_token);
    }

    /*
     * token 变化触发验证策略：
     * - 首次启动（s_last_seen_token 为空）只保存，不验证，确保下一次必定“有变化”再验证
     * - 之后每次只要 token 和上一次接收到的不一样，就发起后端验证
     */
    if (s_last_seen_token[0] == '\0') {
        strncpy(s_last_seen_token, token, sizeof(s_last_seen_token) - 1);
        s_last_seen_token[sizeof(s_last_seen_token) - 1] = '\0';

        strncpy(s_pending_verify_token, token, sizeof(s_pending_verify_token) - 1);
        s_pending_verify_token[sizeof(s_pending_verify_token) - 1] = '\0';
        s_verify_retry_count = 0;

        send_jwtser(token);
        pthread_mutex_lock(&g_verify_mutex);
        g_verify_count = 0;
        pthread_mutex_unlock(&g_verify_mutex);
        my_zlog_info("首次token，发起验证, token=%s", token);
    } else if (strcmp(token, s_last_seen_token) != 0) {
        strncpy(s_last_seen_token, token, sizeof(s_last_seen_token) - 1);
        s_last_seen_token[sizeof(s_last_seen_token) - 1] = '\0';

        strncpy(s_pending_verify_token, token, sizeof(s_pending_verify_token) - 1);
        s_pending_verify_token[sizeof(s_pending_verify_token) - 1] = '\0';
        s_verify_retry_count = 0;

        send_jwtser(token);
        pthread_mutex_lock(&g_verify_mutex);
        g_verify_count = 0;
        pthread_mutex_unlock(&g_verify_mutex);
        my_zlog_info("token变化，发起验证, token=%s", token);
    } else {
        my_zlog_debug("token未变化");
    }


    unsigned long long token_time_s = strtoull(token_time, NULL, 10);
    
    // 转换为秒级时间戳
    time_t token_time_sec = (time_t)(token_time_s );//后端给的时间戳

    time_t current_verify_time=time(NULL);//当前时间戳

    my_zlog_debug("目前时间戳:%1d",(long)current_verify_time); 
    my_zlog_debug("token时间戳:%1d",(long)token_time_sec); 

    if(token_time_sec>current_verify_time){
        if(s_service_verify == TRUE) g_verify_index=0;//验证默认为正确
        my_zlog_debug("g_verify_index= %d ",g_verify_index);
        if(g_verify_count>12000){
            send_jwtser(token);
            my_zlog_debug("JWT超过1分钟触发重新验证, token=%s", token);
            pthread_mutex_lock(&g_verify_mutex);
            g_verify_count=0;
            pthread_mutex_unlock(&g_verify_mutex);
            my_zlog_debug("g_verify_count=%d",g_verify_count);
            } 
    }else {
        my_zlog_warn("JWT验证失败: token已过期, token=%s", token);
        g_verify_index=1;
        my_zlog_debug("g_verify_index= %d ",g_verify_index);
    }

    my_zlog_debug("token: %s", token);
    my_zlog_debug("token_time: %s", token_time);
    return 0;

}

//当接收到2006判断是否验证成功
int message2006_verify(cJSON *body){
    char *status=NULL;
    char *onlyid=NULL;

    cJSON *json_status = cJSON_GetObjectItem(body, "status");
    cJSON *json_onlyid = cJSON_GetObjectItem(body, "only_id");
    

    if(json_status == NULL || json_onlyid==NULL) {
        my_zlog_warn("验证为空");
        s_service_verify = FALSE;
        g_verify_index=1;
        my_zlog_debug("g_verify_index= %d ",g_verify_index);
        return 1;
    }
    status = json_status->valuestring;
    onlyid = json_onlyid->valuestring;

    my_zlog_debug("data: %s", status);
    my_zlog_debug("onlyid: %s", onlyid);
    if(strcmp(onlyid,s_only_id_middle) == 0 && strcmp(status, "1") == 0){
        my_zlog_info("获得验证正确, onlyid=%s", onlyid);
        s_service_verify = TRUE;
        g_verify_index = 0;  /* 后端通过后必须清除失败标志，否则正确 token 仍会提示验证不通过 */
        strcpy(s_secret_key, s_pending_verify_token);
        s_secret_key_index = FALSE;
        s_verify_retry_count = 0;
        s_verify_retry_after_time = 0;
    } else {
        /* 仅当 onlyid 匹配时视为本次验证的回复，否则可能是旧包 */
        if (strcmp(onlyid, s_only_id_middle) == 0) {
            s_verify_retry_count++;
            if (s_verify_retry_count < VERIFY_RETRY_MAX) {
                my_zlog_notice("验证不通过，第%d次，将在下次收到消息且距本次超过%ds后重试, token=%s",
                               s_verify_retry_count, VERIFY_RETRY_INTERVAL_SEC, s_pending_verify_token);
                s_verify_retry_after_time = time(NULL) + VERIFY_RETRY_INTERVAL_SEC;
            } else {
                my_zlog_warn("topic验证超过%d次不通过，禁止使用, token=%s", VERIFY_RETRY_MAX, s_pending_verify_token);
                g_verify_index = 1;
                s_service_verify = FALSE;
                return 2;
            }
        } else {
            my_zlog_warn("获得验证错误，禁止使用, onlyid=%s status=%s", onlyid, status);
            g_verify_index = 1;
            s_service_verify = FALSE;
            return 2;
        }
    }

    return 0;
 }

/*接收到是否打开验证的函数；2013 仅接受 AES 加密 String body，明文一律拒绝*/
int message2013_recverigy_open(cJSON *body_raw)
{
    cJSON *body = NULL;
    char *plain_json = NULL;
    cJSON *verify_status = NULL;

    if (body_raw == NULL) {
        my_zlog_warn("2013 body为空");
        return -1;
    }

    if (cJSON_IsObject(body_raw)) {
        my_zlog_warn("2013 必须加密下发，明文拒绝");
        return -1;
    }

    if (!cJSON_IsString(body_raw) || body_raw->valuestring == NULL) {
        my_zlog_warn("2013 body类型无效");
        return -1;
    }

    if (mqtt_aes_decrypt_body(body_raw->valuestring, MQTT_ENCRYPT_KEY, &plain_json) != 0) {
        my_zlog_warn("2013 body解密失败");
        return -1;
    }

    body = cJSON_Parse(plain_json);
    free(plain_json);
    if (body == NULL) {
        my_zlog_warn("2013 解密后JSON解析失败");
        return -1;
    }

    verify_status = cJSON_GetObjectItem(body, "verify_status");
    if (!cJSON_IsNumber(verify_status)) {
        my_zlog_warn("2013 解密后缺少verify_status");
        cJSON_Delete(body);
        return -1;
    }

    s_verify_open_got_reply = true;
    s_verify_open_query_gave_up = false;

    if (verify_status->valueint == 1) {
        VERIFIED_MODE = TRUE;
        my_zlog_info("开启验证成功(加密校验通过), verify_status=1");
        cJSON_Delete(body);
        return 0;
    }

    if (verify_status->valueint == 0) {
        VERIFIED_MODE = FALSE;
        my_zlog_info("关闭验证成功(加密校验通过), verify_status=0");
        cJSON_Delete(body);
        return 0;
    }

    my_zlog_warn("2013 verify_status无效: %d", verify_status->valueint);
    cJSON_Delete(body);
    return -1;
}

/*发送是否打开验证的mqtt给后端验证*/
int message_sendopen_verify(){
    cJSON *root = cJSON_CreateObject();
    cJSON *body = cJSON_CreateObject();
    cJSON *head = cJSON_CreateObject();

    cJSON_AddNumberToObject(body, "verify_status", 0);

    cJSON_AddNumberToObject(head, "message_type",3013);

    cJSON_AddItemToObject(root, "body", body);
    cJSON_AddItemToObject(root, "head",head);

    char *payload = cJSON_PrintUnformatted(root);

    if(payload==NULL){
        my_zlog_debug("send verify am null");
        cJSON_Delete(root);
        return -1;
    }

    my_zlog_debug("发送验证查询: %s", payload);

    mqtt_publish_to_all(mqtt_topic_pure_number(), payload, 0);
    
    free(payload);
    cJSON_Delete(root);

    return 0;

}

static int verify_open_query_send_once(void) {
    if (message_sendopen_verify() != 0) {
        return -1;
    }
    s_verify_open_send_count++;
    s_verify_open_last_send_time = time(NULL);
    my_zlog_info("发送验证开关查询(3013), 第%d/%d次", s_verify_open_send_count, VERIFY_OPEN_QUERY_MAX);
    return 0;
}

/*发送是否打开验证的mqtt给后端验证初始化*/
int verify_open_index_init(){
    s_verify_open_got_reply = false;
    s_verify_open_query_gave_up = false;
    s_verify_open_send_count = 0;
    s_verify_open_last_send_time = 0;

    return verify_open_query_send_once();
}

void verify_open_query_poll(void) {
    if (s_verify_open_got_reply || s_verify_open_query_gave_up) {
        return;
    }
    if (s_verify_open_last_send_time == 0) {
        return;
    }

    time_t now = time(NULL);
    if (now - s_verify_open_last_send_time < VERIFY_OPEN_QUERY_INTERVAL_SEC) {
        return;
    }

    if (s_verify_open_send_count >= VERIFY_OPEN_QUERY_MAX) {
        my_zlog_warn("验证开关查询(3013)已发送%d次仍未收到后端2013回复，停止重试", VERIFY_OPEN_QUERY_MAX);
        s_verify_open_query_gave_up = true;
        return;
    }

    verify_open_query_send_once();
}

int mqtt_verify_clear_send(char *status){
    cJSON *root = cJSON_CreateObject();
    cJSON *body = cJSON_CreateObject();
    cJSON *head = cJSON_CreateObject();
    
    // 设置body字段
    cJSON_AddStringToObject(body, "verify_clear_item", "clear");
    cJSON_AddStringToObject(body, "verify_clear_status", status);
    
    // 设置head字段
    cJSON_AddNumberToObject(head, "message_type", 3021);
     // 将body和head添加到根对象
    cJSON_AddItemToObject(root, "body", body);
    cJSON_AddItemToObject(root, "head", head);
     // 生成JSON字符串
    char *payload = cJSON_PrintUnformatted(root);

    if(payload==NULL){
        my_zlog_debug("send verify am null");
        cJSON_Delete(root);
        return -1;
    }

    my_zlog_debug("%s",payload);

    mqtt_publish_to_all(mqtt_topic_pure_number(), payload, 0);
    
    free(payload);
    cJSON_Delete(root);

    return 0;


}


void mqtt_verify_data_clear(cJSON *body){
    cJSON *verify_clear_item = cJSON_GetObjectItem(body, "verify_clear_item");
    
    if (verify_clear_item != NULL && cJSON_IsString(verify_clear_item)) {
        const char *status = verify_clear_item->valuestring;
        
        if (strcmp(status, "clear") == 0) {
            my_zlog_info("状态为 clear，执行清理操作");
            pthread_mutex_lock(&g_verify_mutex);
            g_verify_count = 12001;
            pthread_mutex_unlock(&g_verify_mutex);
            // 执行清理逻辑
            mqtt_verify_clear_send("1");

        } else {
            my_zlog_info("状态为: %s", status);
            mqtt_verify_clear_send("0");
        }
    } else {
        my_zlog_warn("verify_clear_item 字段不存在或不是字符串类型");
        mqtt_verify_clear_send("2");
    }
}

