#include "common.h"

// 计算字符串长度
int _strlen(char *str)
{
    char *_p = NULL;

    if (str == NULL)
        return 0;

    _p = strchr(str, '\0');

    if (_p == NULL)
        return 0;

    return _p - str;
}

// 自定义 printf 函数
void _printf(const char *format, ...)
{
    va_list args;
    va_start(args, format);

    // 打印到控制台
    vprintf(format, args);
    va_end(args);               // 结束对变参列表的处理

    // 重新启动变参列表
    va_start(args, format);

    // 打开日志文件（追加模式）
    FILE *log_file = fopen(PRINT_LOG_FILE, "a");
    if (log_file != NULL) {
        // 获取当前时间
        time_t now = time(NULL);
        struct tm local_time;
        localtime_r(&now, &local_time);
        char time_str[20];      // YYYY-MM-DD HH:MM:SS 格式
        strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &local_time);

        // 打印时间戳到日志文件
        fprintf(log_file, "[%s] ", time_str);

        // 打印内容到日志文件
        vfprintf(log_file, format, args);

        // 关闭日志文件
        fclose(log_file);
    } else {
        perror("Unable to open log file");
    }

    
    va_end(args);               // 结束对变参列表的处理
}

void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM])
{
    int i = 0;
    char *result = NULL;
    char temp[WHITELIST_IP_NUM];                 // 创建一个足够大的副本缓冲区

    // 复制原始字符串到副本
    strncpy(temp, string, sizeof(temp) - 1);
    temp[sizeof(temp) - 1] = '\0';        // 确保字符串以 '\0' 结尾

    result = strtok(temp, delims);               // 使用副本进行拆分
    while (result != NULL && i < WHITELIST_IP_NUM)
    {
        strncpy(whitelist_ip[i], result, WHITELIST_IP_NUM - 1);
        whitelist_ip[i][WHITELIST_IP_NUM - 1] = '\0';   // 确保每个元素以 '\0' 结尾
        i++;
        result = strtok(NULL, delims);
    }
}

// IP段白名单对比
int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM])
{
    int i;

    for (i = 0; i < WHITELIST_IP_NUM; i++) {  // 从 i = 0 开始
        // 如果白名单 IP 是空字符串，跳出循环
        if (whitelist_ip[i][0] == '\0') {
            break;
        }

        // 对比client_ip的前缀是否与白名单中的IP段匹配
        if (strncmp(client_ip, whitelist_ip[i], strlen(whitelist_ip[i])) == 0) {
            return 1;  // 匹配成功
        }
    }

    return 0;  // 未找到匹配
}


// 地域段白名单对比
int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
{
    int i;
    char *p;

    for (i = 0; i < WHITELIST_IP_NUM; i++) {
        // 如果region_list[i]为空字符串，跳出循环
        if (region_list[i][0] == '\0') {
            break;
        }

        // 在str中查找region_list[i]
        p = strstr(str, region_list[i]);
        if (p != NULL) {
            return 1; // 匹配成功，返回1
        }
    }

    return 0; // 没有匹配，返回0
}

int8_t _copy_new_mem(char *src, int src_len, char **dest)
{
    *dest = (char *)malloc(src_len + 1);
    if (*dest == NULL)
        return 1;
    memcpy(*dest, src, src_len);
    *((*dest) + src_len) = '\0';

    return 0;
}

char *_time()
{
    char temp[BUFFER];
    char *wday[] = { "0", "1", "2", "3", "4", "5", "6" };
    time_t t;
    struct tm *p;
    time(&t);
    p = localtime(&t);          // 取得当地时间

    memset(temp, 0, BUFFER);
    snprintf(temp, BUFFER, "[%d/%02d/%02d %s %02d:%02d:%02d] ", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday, wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);

    return strdup(temp);
}

int is_valid_ip(const char *ip)
{
    struct sockaddr_in sa;
    // 尝试将字符串转换为IPv4地址
    int result = inet_pton(AF_INET, ip, &(sa.sin_addr));

    return result != 0;
}

int _nice(int increment)
{
    int oldprio = getpriority(PRIO_PROCESS, getpid());
    printf("%d\n", oldprio);

    return setpriority(PRIO_PROCESS, getpid(), oldprio + increment);
}

// 判断命令是否存在
int _command_exists(const char *command)
{
    char buffer[BUFFER];
    snprintf(buffer, sizeof(buffer), "%s > /dev/null 2>&1", command);
    int status = system(buffer);

    return (status == 0);
}

// 定义一个函数，执行命令并返回输出
char *_execute_command(const char *command) {
    FILE *fp;
    char buffer[1024];
    char *output = NULL;
    size_t output_size = 0;
    size_t total_read = 0;

    // 打开管道，执行命令
    fp = popen(command, "r");
    if (fp == NULL) {
        perror("popen");
        return NULL;
    }

    // 读取命令的输出
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        size_t len = strlen(buffer);
        if (total_read + len + 1 > output_size) {
            output_size = output_size == 0 ? 128 : output_size * 2;
            char *new_output = realloc(output, output_size);
            if (new_output == NULL) {
                perror("realloc");
                free(output);  // 释放已分配的内存
                pclose(fp);     // 关闭管道
                return NULL;
            }
            output = new_output;
        }
        // 复制内容并增加总计读取的长度
        strcpy(output + total_read, buffer);
        total_read += len;
    }

    // 确保输出以 null 结尾
    if (output_size > 0) {
        output[total_read] = '\0';
    }

    // 关闭管道
    if (pclose(fp) == -1) {
        perror("pclose");
        free(output);  // pclose 失败时释放内存
        return NULL;
    }

    return output;
}

