#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <linux/input.h>
#include <pthread.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <stdbool.h>

// cmd length
#define CMD_LENGTH 100
// 通用字符串
#define CS_ECHO "echo "
#define CS_REDIRECT " > "
#define CS_IN "in"
#define CS_OUT "out"
#define CS_NORMAL "normal"
#define CS_INVERSE "inverse"
// rtc
#define CS_RTC_DATE "date "
#define CS_RTC_HWCLOCK "hwclock "

#define HWCLOCK_W " -w"
#define DATE_S " -s"
#define BUFFER_SIZE 1024
#define KEYWORDS "re867a_test"

int globalSignalValue = -61;
// 公共函数
int retIntBits(int value)
{
    int bit = 0;
    while (1)
    {
        int res = value % 10;
        int resEx = value / 10;
        value /= 10;
        if (res != 0 || resEx != 0)
        {
            bit++;
        }
        else
        {
            if (bit == 0)
            {
                bit = 1;
            }
            return bit;
        }
    }
}
int strToInt(char c)
{
    int res = -1;
    res = c - '0';
    return res;
}
char *intToStr(int value)
{
    int bits = retIntBits(value);
    char *p = (char *)malloc(bits + 1);
    int cnt = 0;
    for (cnt = 0; cnt < bits; cnt++)
    {
        *(p + cnt) = '0' + value / pow(10, bits - cnt - 1);
        value %= (int)pow(10, bits - cnt - 1);
    }
    *(p + cnt) = '\0';
    return p;
}

bool contains_string(const char *filename, const char *target_string)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        perror("Error opening file");
        return false;
    }

    char buffer[1024]; // 缓冲区大小，可以根据需要调整
    size_t bytesRead;
    bool found = false;

    // 逐块读取文件内容
    while ((bytesRead = fread(buffer, 1, sizeof(buffer) - 1, file)) > 0)
    {
        // 确保字符串在缓冲区内以null终止
        buffer[bytesRead] = '\0';

        // 使用strstr搜索目标字符串
        if (strstr(buffer, target_string) != NULL)
        {
            found = true;
            break; // 找到后退出循环
        }

        // 如果字符串可能在块边界被分割，可以继续搜索剩余的缓冲区（如果需要）
        // 但在这个例子中，我们假设目标字符串不会在块边界被分割
    }
    printf("++++++++++buffer=%s\n", buffer);
    fclose(file);
    return found;
}

typedef struct EVEN_WIFI_DATA_ANALYSIS
{
    char *MAC;
    char *delay;
    char *db;
    char *type;
    char *name;
} EVEN_WIFI_DATA_ANALYSIS;

#define WIFI_PACKAGE_WORD_NUMBER 5
EVEN_WIFI_DATA_ANALYSIS wifi_analysis_package(char *str, unsigned int length)
{
    // printf("start run wifi_analysis_package function\n");
    EVEN_WIFI_DATA_ANALYSIS ewda;
    char *head_p = str;
    printf("188 str=%s\n", str);
    for (int i = 0; i < length; i++)
    {
        printf("188 str=%x\n", str[i]);
    }
    usleep(500000);

    char *token;
    char *saveptr = NULL; // strtok_r 需要这个，但 strtok 不需要

    // 注意：strtok 会修改原始字符串，因为它用 '\0' 替换分隔符
    // 如果原始字符串不能被修改，你需要先复制它

    // 获取第一个令牌
    const char *HTbuffer = "\t";
    token = strtok(str, HTbuffer);
    int count = 0;
    while (token != NULL && count <= 5)
    {
        printf("Token %d: %s\n", count + 1, token);
        if (count == 2)
        {
            ewda.db = token;
        }
        else if (count == 4)
        {
            ewda.name = token;
        }
        // 获取下一个令牌
        token = strtok(NULL, HTbuffer);
        count++;
    }
    printf("ewda.db: %s\n", ewda.db);
    printf("ewda.name: %s\n", ewda.name);
    return ewda;
    char *p_buf[sizeof(ewda) / sizeof(char *)] = {ewda.MAC,
                                                  ewda.delay,
                                                  ewda.db,
                                                  ewda.type,
                                                  ewda.name};
    for (int cnt = 0; cnt < WIFI_PACKAGE_WORD_NUMBER;)
    {
        char *p = strstr(head_p, " ");
        if (p - head_p > 1)
            cnt++;
        else
        {
            head_p = p;
            continue;
        }
        p_buf[cnt] = (char *)malloc(p - head_p);
        memcpy(p_buf[cnt], head_p, p - head_p);
        head_p = p;
        printf("p_buf[cnt]=%s\n", p_buf[cnt]);
    }
    printf("ewda.MAC=%s\n", ewda.MAC);
    return ewda;
}

int getWifiSignalLevel(char *name)
{
    return globalSignalValue;
}

int isWifi(char *name)
{
    FILE *fp_in;
    char buffer[BUFFER_SIZE] = {0};
    size_t bytesRead;
    int testFlag = 0;

    // 使用 popen 执行命令
    system("killall wpa_supplicant");
    system("wpa_supplicant -i wlan0 -c /usr/app/quicknode/tests/867factory_test/test.conf -B -d");

    struct timespec ts;
    ts.tv_sec = 4;        // 秒
    ts.tv_nsec = 0;       // 纳秒
    nanosleep(&ts, NULL); // 延时1秒

    system("wpa_cli -i wlan0 scan");
    // 使用 popen 执行命令
    // fp_in = popen("wpa_cli -i wlan0 -p /etc/wifi/wpa_supplicant/sockets scan_result | grep 're832test' | grep 'signal:' | awk '{print $2}'", "r"); // 假设这是一个有效的命令
    fp_in = popen("wpa_cli -i wlan0 scan_result | grep 're867a_test' ", "r"); // 假设这是一个有效的命令
    if (fp_in == NULL)
    {
        perror("popen failed");
        return 1;
    }

    // 读取扫描结果
    if (fgets(buffer, sizeof(buffer), fp_in) != NULL)
    {
        printf("++++++++++++++popen 178 result is %s\n", buffer);
        EVEN_WIFI_DATA_ANALYSIS info = wifi_analysis_package(buffer, strlen(buffer));
        // 打印结果以验证
        // printf("MAC: %s\n", info.MAC);
        // printf("Freq: %s\n", info.delay);
        printf("Signal: %s\n", info.db);
        // printf("Security: %s\n", info.type);
        printf("SSID: %s\n", info.name);
        globalSignalValue = atoi(info.db);
        if ((strstr(info.name, "re867a_test") != NULL) && strlen(info.name) == 12)
        {
            printf("++++++++++++++++++found right SSID,continue!\n");
            printf("++++++++++++++++++Signal Level is OK!");
            testFlag = 1; // 表示wifi查找成功
        }
        else
        {
            printf("++++++++++++++++++Not Found right SSID,return!\n");
            testFlag = 0; // 表示wifi查找失败
            printf("SSID: %s\n", info.name);
            printf("SSID length: %d\n", strlen(info.name));
        }
    }
    // printf("++++++++++++++popen scan re867a_test result is%s\n", buffer);
    // 检查并处理任何可能的错误
    else
    {
        testFlag = 0; // 表示wifi测试失败
    }
    if (ferror(fp_in))
    {
        perror("fread error");
    }
    pclose(fp_in);
    system("killall wpa_supplicant");
    return testFlag;
}

int initWifi(char *name)
{
    printf("start run initWifi function\n");
    system("wpa_supplicant -i wlan0 -c /usr/app/quicknode/tests/867factory_test/test.conf -B -d");
}

char *getVersion(char *name)
{
    FILE *fp;
    char path[1024];

    // 注意：这里将整个命令（包括管道）用引号括起来，并指定/bin/sh来执行它
    fp = popen("fw_printenv | grep swu_version", "r");
    // fp = popen("/bin/sh -c 'fw_printenv | grep swu_version'", "r");
    if (fp == NULL)
    {
        printf("Failed to run command\n");
        exit(1);
    }

    // 读取输出
    while (fgets(path, sizeof(path) - 1, fp) != NULL)
    {
        printf("path=%s", path);
    }

    char *equal_pos = strchr(path, '=');
    if (equal_pos == NULL)
    {
        // 如果没有找到'='，返回NULL
        return NULL;
    }

    // 分配足够的内存来存储'='之后的部分（包括终止符'\0'）
    size_t len = strlen(equal_pos + 1) + 1; // +1 跳过'='字符，+1 用于'\0'
    char *result = (char *)malloc(len);
    if (result == NULL)
    {
        // 如果内存分配失败，返回NULL
        return NULL;
    }

    // 复制'='之后的部分到新的字符串中
    strncpy(result, equal_pos + 1, len); // +1 跳过'='字符
    // printf("result=%s\n", result);
    // 关闭文件流
    pclose(fp);
    return result;
    // return 0;
}
char *get_wifi_mac() {
    FILE *fp;
    static char mac_addr[32];
    char cmd[128] = "ifconfig wlan0 2>/dev/null | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'";
    char buffer[64];

    // 执行命令并读取输出
    fp = popen(cmd, "r");
    if (fp == NULL) {
        perror("popen failed");
        return NULL;
    }

    // 读取 MAC 地址
    if (fgets(buffer, sizeof(buffer), fp) != NULL) {
        // 去除可能的换行符
        buffer[strcspn(buffer, "\n")] = '\0';
        if (strlen(buffer) > 0) {
            strncpy(mac_addr, buffer, sizeof(mac_addr));
            pclose(fp);
            return mac_addr; // 成功
        }
    }

    pclose(fp);
    return NULL; // 失败
}
int syncSave(char *name)
{
    printf("Save product_res.json\n");
    system("sync");
    return 1;
}
