#include <time.h>
#include "mqtt_verify.h"
#include "common.h"
#include <openssl/evp.h>
#include <openssl/aes.h> 
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/err.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

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);

    for(int i=0;i<g_mqtt_cam_config_t->mqtt_count;i++){
        mosquitto_publish(g_clients_t[i].mosq, NULL, mqtt_topic_pure_number(), strlen(payload), payload, 0, false); 
    }
    
    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_notice("距上次失败已过%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_notice("首次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_notice("token变化，发起验证, token=%s", token);
    } else {
        my_zlog_info("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_notice("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_info("token: %s", token);
    my_zlog_info("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_debug("验证为空");
        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_debug("获得验证正确");
        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_debug("获得验证错误，禁止使用");
            g_verify_index = 1;
            s_service_verify = FALSE;
            return 2;
        }
    }

    return 0;
 }

/*接收到是否打开验证的函数*/
int message2013_recverigy_open(cJSON *body){
    cJSON *verifty_open_index = cJSON_GetObjectItem(body, "verify_status");
    if(verifty_open_index == NULL){
        my_zlog_debug("接收验证是否打开为空");
        return -1;
    }
    int verifty_open = verifty_open_index->valueint;
     my_zlog_debug("verifty:%d",verifty_open);
     if(verifty_open == 0){
        VERIFIED_MODE=FALSE;
        my_zlog_debug("verify close");
     }else {
        VERIFIED_MODE=TRUE;
        my_zlog_debug("verify open");
     }
    return 0;
}

/*发送是否打开验证的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);

    for(int i=0;i<g_mqtt_cam_config_t->mqtt_count;i++){
        mosquitto_publish(g_clients_t[i].mosq, NULL, mqtt_topic_pure_number(), strlen(payload), payload, 0, false); 
    } 
    
    free(payload);
    cJSON_Delete(root);

    return 0;

}   

/*发送是否打开验证的mqtt给后端验证初始化*/
int verify_open_index_init(){
    if(message_sendopen_verify()!=0){
        return -1;
    }

    return 0;
}

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);

    for(int i=0;i<g_mqtt_cam_config_t->mqtt_count;i++){
        mosquitto_publish(g_clients_t[i].mosq, NULL, mqtt_topic_pure_number(), strlen(payload), payload, 0, false); 
    } 
    
    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_info("verify_clear_item 字段不存在或不是字符串类型");
        mqtt_verify_clear_send("2");
    }
}

