#include "drv_tcp.h"
#define BUFFER_SIZE 1024

void getInterfacesAndIPs(char *interfaces[], char *ips[], int *count) {
    struct ifconf ifc;
    struct ifreq *ifr;
    int sockfd;
    char buffer[BUFFER_SIZE];
    char ipAddress[INET_ADDRSTRLEN];
    // 创建套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("创建套接字失败");
        return;
    }
    ifc.ifc_buf = buffer;
    ifc.ifc_len = sizeof(buffer);
    // 获取网络接口配置信息
    if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
        perror("获取网络接口配置失败");
        close(sockfd);
        return;
    }
    ifr = (struct ifreq *)ifc.ifc_buf;
    int numInterfaces = ifc.ifc_len / sizeof(struct ifreq);
    *count = numInterfaces;
    for (int i = 0; i < numInterfaces; i++) {
        printf("网口名字: %s\n", ifr[i].ifr_name);
        interfaces[i] = strdup(ifr[i].ifr_name);
        // 获取IP地址
        if (ioctl(sockfd, SIOCGIFADDR, &ifr[i]) < 0) {
            perror("获取IP地址失败");
        } else {
            struct sockaddr_in *addr = (struct sockaddr_in *)&ifr[i].ifr_addr;
            inet_ntop(AF_INET, &addr->sin_addr, ipAddress, INET_ADDRSTRLEN);
            printf("IP地址: %s\n", ipAddress);
            ips[i] = strdup(ipAddress);
        }
    }
    close(sockfd);
}


// 关闭与某个网口相关的套接字并释放内存
void closeAndFree(int server_fd, int new_socket, char *interface, char *ip) {
    close(new_socket);
    close(server_fd);
    free(interface);
    if (ip!= NULL) {
        free(ip);
    }
}

// 线程函数,用于处理每个网口的监听和连接
void *tcpServeThread(void *arg) {
    int port = 8888;
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);
    char buffer[BUFFER_SIZE];
    char *interface = ((char **)arg)[0];
    char *ip = ((char **)arg)[1];
    int optval = 1;

    // printf("Port : %d", port);
    // 创建套接字
    label:
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("套接字创建失败");
        pthread_exit(NULL);
    }

    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
    perror("设置套接字选项失败");
    close(server_fd);
    exit(EXIT_FAILURE);
}
    printf("设置套接字选项成功\n");
    // 设置服务器地址结构体
    address.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &address.sin_addr);
    address.sin_port = htons(port);

    // 绑定套接字到指定地址和端口
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("绑定失败");
        closeAndFree(server_fd, -1, interface, ip);
        pthread_exit(NULL);
    }

    // 监听端口,等待客户端连接
    if (listen(server_fd, 3) < 0) {
        perror("监听失败");
        closeAndFree(server_fd, -1, interface, ip);
        pthread_exit(NULL);
    }

    printf("在端口 %s(IP: %s,端口:%d)上启动服务器,正在等待客户端连接...\n", interface, ip, port);

    // 接受客户端连接
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) {
        perror("接受连接失败");
        closeAndFree(server_fd, -1, interface, ip);
        pthread_exit(NULL);
    }

    printf("客户端已连接到网口 %s(IP: %s)\n", interface, ip);

    char client_ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &(address.sin_addr), client_ip, INET_ADDRSTRLEN);
    printf("Client IP: %s\n", client_ip);

    while (1) {
        // 接收客户端发送的数据
        memset(buffer, 0, BUFFER_SIZE);
        if (recv(new_socket, buffer, BUFFER_SIZE, 0) < 0) {
            perror("接收数据失败");
            break;
        }

        if (strlen(buffer) == 0) {
            // 客户端断开连接
            printf("客户端已断开连接,从网口 %s(IP: %s)断开。\n", interface, ip);
            close(new_socket);
            close(server_fd);
            sleep(1);
            goto label;
        }

        printf("端口%s,ip:%s,端口号:%d,收到客户端消息:%s\n", interface, ip, port, buffer);

        // 向客户端发送相同的数据作为回复
        if (send(new_socket, buffer, strlen(buffer), 0) < 0) {
            perror("发送数据失败");
            break;
        }
    }

    // 关闭与该网口相关的套接字并释放内存
    closeAndFree(server_fd, new_socket, interface, ip);

    pthread_exit(NULL);
}

void tcpServe(int port) {
    char *interfaces[100];
    char *ips[100];
    int numInterfaces;

    // 获取本地所有网口名称及对应的IP地址
    getInterfacesAndIPs(interfaces, ips, &numInterfaces);

    pthread_t threads[100];
    char * thread_args[100][3];

    for (int i = 0; i < numInterfaces; i++) {
        if (ips[i] == NULL) {
            continue;
        }

        // char * portChar;
        // sprintf(portChar, "%d", port);
        // 为每个线程准备参数
        // thread_args[i][0] = portChar;
        thread_args[i][0] = interfaces[i];
        thread_args[i][1] = ips[i];

        // 创建线程
        if (pthread_create(&threads[i], NULL, tcpServeThread, &thread_args[i])!= 0) {
            perror("线程创建失败");
            closeAndFree(-1, -1, interfaces[i], ips[i]);
            continue;
        }
    }

    // 等待所有线程完成
    for (int i = 0; i < numInterfaces; i++) {
        if (threads[i]!= 0) {
            pthread_join(threads[i], NULL);
        }
    }
}