#include "device_identity.h"
#include "device_fileopen.h"
#include "common.h"
#include "drivers_common.h"

static char s_app2dev_topic[23];
static char s_dev2app_topic[23];
static char s_pure_topic[15];
static char s_ser2dev_topic[23];

static bool s_device_name_exists=0;//查找设备号状态机，如果id是不属于任何类型

/*提早声明*/
int device_mqtt_topic_init();

/*纯设备号*/
char *mqtt_topic_pure_number(){
    return s_pure_topic;
}

/*app2dev设备号*/
char *mqtt_topic_app2dev_number(){
    return s_app2dev_topic;
}

/*dev2app设备号*/
char *mqtt_topic_dev2app_number(){
    return s_dev2app_topic;
}

/*ser2dev设备号*/
char *mqtt_topic_ser2dev_number(){
    return s_ser2dev_topic;
}

// 哈希函数：简单的字符串哈希
unsigned int hash(const char *str, int tableSize) {
    unsigned int hash = 0;
    while (*str) {
        hash = (hash << 5) + *str++;
    }
    return hash % tableSize;
}

// 创建哈希表
HashTable_t* createHashTable(int size) {
    HashTable_t *hashTable = (HashTable_t *)malloc(sizeof(HashTable_t));
    if (hashTable == NULL) {
        // 这里可以加错误处理，比如返回 NULL
        return NULL;
    }
    hashTable->size = size;
    hashTable->table = (HashEntry_t **)malloc(sizeof(HashEntry_t *) * size);
    if (hashTable->table == NULL) {
        free(hashTable);
        return NULL;
    }
    for (int i = 0; i < size; i++) {
        hashTable->table[i] = NULL;
    }
    return hashTable;
}

// 插入元素到哈希表
void insert(HashTable_t *HashTable_t, const char *key, CodeEnum_t value) {
    unsigned int index = hash(key, HashTable_t->size);
    HashEntry_t *newEntry = (HashEntry_t *)malloc(sizeof(HashEntry_t));
    newEntry->key = key;
    newEntry->value = value;
    newEntry->next = HashTable_t->table[index];
    HashTable_t->table[index] = newEntry;
}

// 查找元素
CodeEnum_t find(HashTable_t *HashTable_t, const char *key) {
    unsigned int index = hash(key, HashTable_t->size);
    HashEntry_t *entry = HashTable_t->table[index];
    while (entry) {
        if (strcmp(entry->key, key) == 0) {
            return entry->value;
        }
        entry = entry->next;
    }
    return -1;  // 未找到
}

int hash_insert_init(HashTable_t *HashTable_t) {

    // 插入已有的代码
    insert(HashTable_t, "0101", CAR_0101);
    insert(HashTable_t, "0102", CAR_0102);
    insert(HashTable_t, "0103", CAR_0103);
    insert(HashTable_t, "0104", CAR_0104);
    insert(HashTable_t, "0105", CAR_0105);
    insert(HashTable_t, "0201", TANK_0201);
    insert(HashTable_t, "0202", TANK_0202);
    insert(HashTable_t, "0203", TANK_0203);
    insert(HashTable_t, "0204", TANK_0204);
    insert(HashTable_t, "0206", TANK_0206);
    insert(HashTable_t, "0207", TANK_0207);   
    insert(HashTable_t, "0301", SHIP_0301);
    insert(HashTable_t, "0401", PAO_0401);
    insert(HashTable_t, "0404", PAO_0404);
    insert(HashTable_t, "0405", PAO_0405);
    insert(HashTable_t, "0403", PGGPS_0403);
    insert(HashTable_t, "0501", ROBOT_DOG0501);
}

int device_judg(CodeEnum_t code,char *sub_str) {
    if (code == CAR_0101) {
       device_init(DEVICE_CAR0101);
        my_zlog_info("使用大车，型号%s",sub_str);
    }else if(code == CAR_0102) {
        device_init(DEVICE_CAR0102);
        my_zlog_info("使用小车，型号%s",sub_str);
    }else if(code == CAR_0103) {
        device_init(DEVICE_CAR0103);
        my_zlog_info("使用挖掘机，型号%s",sub_str);
    }else if(code == CAR_0104) {
        device_init(DEVICE_CAR0104);
        my_zlog_info("使用推土机，使用型号%s",sub_str);
    }else if (code == CAR_0105) {
        device_init(DEVICE_CAR0105);
        my_zlog_info("使用人坐超大车，型号%s",sub_str);
    }else if(code == TANK_0202) {
        device_init(DEVICE_TANK0202);
        my_zlog_info("使用型号%s",sub_str);
    }else if(code == TANK_0203) {
        device_init(DEVICE_TANK0203);
        my_zlog_info("使用M1A2坦克，型号%s",sub_str);
    }else if(code == TANK_0204) {
        device_init(DEVICE_TANK0204);
        my_zlog_info("使用美卡隆坦克，型号%s",sub_str);
    }else if(code == TANK_0206) {
        device_init(DEVICE_TANK0206);
        my_zlog_info("使用水坦克，型号%s",sub_str);
    }else if(code == TANK_0207) {
        device_init(DEVICE_TANK0207);
        my_zlog_info("使用射水弹坦克，型号%s",sub_str);
    }else if(code == SHIP_0301) {
        device_init(DEVICE_SHIP0301);
        my_zlog_info("使用34号船，型号%s",sub_str);
    }else if(code ==PAO_0401) {
        device_init(DEVICE_PAO_PTZ0401);
        my_zlog_info("使用型号%s",sub_str);   
    }else if(code ==PAO_0404) {
        device_init(DEVICE_PAO_PTZ0404);
        my_zlog_info("使用型号%s",sub_str);   
    }else if(code ==PAO_0405) {
        device_init(DEVICE_PAO_PTZ0405);
        my_zlog_info("使用云台0405，型号%s",sub_str);   
    }else if(code ==PGGPS_0403) {
        device_init(DEVICE_PG_GPS0403);
        my_zlog_info("使用定位设备%s",sub_str);   
    }else if(code ==ROBOT_DOG0501) {
        device_init(DEVICE_ROBOT_DOG0501);
        my_zlog_info("使用型号%s",sub_str);   
    }else {
        my_zlog_error("没有找到设备号,尝试启用备用mqtt,topic进行改名");
        s_device_name_exists=1;
    }
    return 0;
}

/*
设备mqtt的topic初始化函数
*/
int device_mqtt_topic_init() {
    char *readmidbuf=device_id_function(); //读取代码
    if(strlen(readmidbuf) > 14 && readmidbuf[14]=='\n') readmidbuf[14]='\0';//将\n去除

    const char *readbuf = readmidbuf;

    //将第3个和第4个字符提取出来
    char *sub_str=malloc(5);
    sub_str[0]=readbuf[2];
    sub_str[1]=readbuf[3];
    sub_str[2]=readbuf[4];
    sub_str[3]=readbuf[5];
    sub_str[4]='\0';
    my_zlog_info("开始初始化了");

    HashTable_t *HashTable_t = createHashTable(INITIAL_TABLE_SIZE);//创造hash表
    hash_insert_init(HashTable_t);//hash表初始化
    CodeEnum_t code = find(HashTable_t, sub_str);
    
    if(device_judg(code,sub_str) == 0) my_zlog_info("判断成功了");

    free(sub_str);
          
    delay_s(10);
    if(s_device_name_exists == 0) {
        sprintf(s_app2dev_topic,"app2dev/%s",readbuf);
        sprintf(s_dev2app_topic,"dev2app/%s",readbuf);
        sprintf(s_pure_topic,"%s",readbuf);
        sprintf(s_ser2dev_topic,"ser2dev/%s",readbuf);
    } else {
        sprintf(s_app2dev_topic,"app2dev/%s","00000000000000");
        sprintf(s_dev2app_topic,"dev2app/%s","00000000000000");
        sprintf(s_pure_topic,"%s","00000000000000");
        sprintf(s_ser2dev_topic,"ser2dev/%s","00000000000000");
    }

    my_zlog_info("1:%s,2:%s,3:%s,4:%s",s_app2dev_topic,s_dev2app_topic,s_pure_topic,s_ser2dev_topic);
    return 0;
}
