#include <stdbool.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
#include "wave.h"  // 包含波形表和TABLE_SIZE定义

// 配置参数定义
#define PORT                5000        // 服务器端口
#define BUFFER_SIZE         1024        // 数据缓冲区大小
#define FRAME_HEADER1       0x55        // 命令帧头部1
#define FRAME_HEADER2       0xA5        // 命令帧头部2
#define FRAME_TAIL          0xF0        // 命令帧尾部
#define FRAME_SIZE          8           // 固定命令帧长度(8字节)
#define SEND_INTERVAL_MS    10          // 发送间隔(毫秒)

// 波形发送模式
#define MODE_SINE_ONLY      1           // 仅发送正弦波
#define MODE_TRIANGLE_ONLY  2           // 仅发送三角波
#define MODE_ALTERNATING    3           // 交替发送正弦和三角波

// 波形类型
#define WAVE_SINE           1           // 正弦波
#define WAVE_TRIANGLE       2           // 三角波

// 全局变量
int server_fd;
int client_socket = -1;
uint32_t wave_mode = MODE_SINE_ONLY;     // 波形发送模式 (1-3)
uint32_t total_bytes = 0;                // 总发送字节数
bool sending_enabled = false;            // 发送使能标志
uint8_t *data_buffer = NULL;             // 数据缓冲区
size_t data_sent = 0;                    // 已发送字节数
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t send_thread;
bool server_running = true;

// 带时间戳的日志函数
void log_message(const char *format, ...) {
//    time_t now;
//    time(&now);
//    char time_str[26];
//    ctime_r(&now, time_str);
//    time_str[strlen(time_str) - 1] = '\0';  // 移除换行符
//
//    printf("[%s] ", time_str);
//    va_list args;
//    va_start(args, format);
//    vprintf(format, args);
//    va_end(args);
//    printf("\n");
}

// 生成波形数据
// 根据模式生成对应波形数据:
// 1-仅正弦波, 2-仅三角波, 3-交替发送正弦和三角波
uint8_t *generate_wave_data(size_t sample_count, size_t *out_size) {
    if (wave_mode == MODE_SINE_ONLY) {
        // 仅正弦波模式: 每个采样点2字节
        *out_size = sample_count * 2;
        uint8_t *wave = malloc(*out_size);
        if (!wave) return NULL;

        for (size_t i = 0; i < sample_count; i++) {
            int16_t value = sine_table[i % TABLE_SIZE] - 2048;
            // 12位数据打包: 高4位 + 低8位
            wave[2*i + 1] = ((value >> 8) & 0x0F);  // 高4位
            wave[2*i + 0] = value & 0xFF;            // 低8位
        }
        return wave;
    }
    else if (wave_mode == MODE_TRIANGLE_ONLY) {
        // 仅三角波模式: 每个采样点2字节
        *out_size = sample_count * 2;
        uint8_t *wave = malloc(*out_size);
        if (!wave) return NULL;

        for (size_t i = 0; i < sample_count; i++) {
            int16_t value = triangle_table[i % TABLE_SIZE] - 2048;
            // 12位数据打包: 高4位 + 低8位
            wave[2*i + 1] = ((value >> 8) & 0x0F);  // 高4位
            wave[2*i + 0] = value & 0xFF;            // 低8位
        }
        return wave;
    }
    else if (wave_mode == MODE_ALTERNATING) {
        // 交替模式: 每个采样对4字节(正弦+三角)
        *out_size = sample_count * 4;
        uint8_t *wave = malloc(*out_size);
        if (!wave) return NULL;

        for (size_t i = 0; i < sample_count; i++) {
            // 正弦波数据
            int16_t sine_val = sine_table[i % TABLE_SIZE] - 2048;
            wave[4*i + 1] = ((sine_val >> 8) & 0x0F);
            wave[4*i + 0] = sine_val & 0xFF;

            // 三角波数据
            int16_t tri_val = triangle_table[i % TABLE_SIZE] - 2048;
            wave[4*i + 3] = ((tri_val >> 8) & 0x0F);
            wave[4*i + 2] = tri_val & 0xFF;
        }
        return wave;
    }

    // 无效模式
    *out_size = 0;
    return NULL;
}

// 数据发送线程
void *send_data_thread(void *arg) {
    while (server_running) {
        pthread_mutex_lock(&mutex);

        if (sending_enabled && client_socket != -1 && total_bytes > 0 && data_buffer) {
            // 检查是否发送完成
            if (data_sent >= total_bytes) {
                log_message("send data finished (mode: %d)", wave_mode);
                sending_enabled = false;
                free(data_buffer);
                data_buffer = NULL;
                data_sent = 0;
                pthread_mutex_unlock(&mutex);
                usleep(SEND_INTERVAL_MS * 1000);
                continue;
            }

            // 计算本次发送大小
            size_t remaining = total_bytes - data_sent;
            size_t send_size = (remaining > BUFFER_SIZE) ? BUFFER_SIZE : remaining;

            // 发送数据
            ssize_t bytes_sent = send(client_socket, data_buffer + data_sent, send_size, 0);
            if (bytes_sent > 0) {
                data_sent += bytes_sent;
                log_message("sent : %zd bytes, total: %zu/%u (mode: %d)",
                          bytes_sent, data_sent, total_bytes, wave_mode);
            } else if (bytes_sent < 0) {
                log_message("send error");
                sending_enabled = false;
            }
        }

        pthread_mutex_unlock(&mutex);
        usleep(SEND_INTERVAL_MS * 1000);  // 控制发送速率
    }
    return NULL;
}

// 处理接收到的数据
void process_received_data(uint8_t *buffer, ssize_t len) {
    static uint8_t recv_buf[BUFFER_SIZE * 2];  // 接收缓冲区
    static size_t buf_len = 0;

    // 防止缓冲区溢出
    if (buf_len + len > sizeof(recv_buf)) {
        log_message("Receive buffer overflow, discarding partial data");
        buf_len = 0;
    }
    memcpy(recv_buf + buf_len, buffer, len);
    buf_len += len;

    // 解析完整帧
    while (buf_len >= FRAME_SIZE) {
        int frame_start = -1;
        // 查找帧头和帧尾
        for (int i = 0; i <= buf_len - FRAME_SIZE; i++) {
            if (recv_buf[i] == FRAME_HEADER1 &&
                recv_buf[i+1] == FRAME_HEADER2 &&
                recv_buf[i+7] == FRAME_TAIL) {
                frame_start = i;
                break;
            }
        }

        if (frame_start == -1) {
            // 未找到完整帧,保留可能的帧头部分
            if (buf_len > FRAME_SIZE - 1) {
                memmove(recv_buf, recv_buf + buf_len - (FRAME_SIZE - 1), FRAME_SIZE - 1);
                buf_len = FRAME_SIZE - 1;
            }
            break;
        }

        // 解析帧数据
        uint8_t frame_addr = recv_buf[frame_start + 2];
        uint32_t frame_data = (recv_buf[frame_start + 3] << 24) |
                             (recv_buf[frame_start + 4] << 16) |
                             (recv_buf[frame_start + 5] << 8) |
                             recv_buf[frame_start + 6];
        log_message("Received Data Frame - addr: %hhu, data: 0x%08X", frame_addr, frame_data);

        pthread_mutex_lock(&mutex);
        // 处理不同地址的指令
        switch (frame_addr) {
            case 0:  // 发送使能
                sending_enabled = (frame_data != 0);
                log_message("send enable: %s", sending_enabled ? "on" : "off");

                if (sending_enabled && total_bytes > 0) {
                    // 生成波形数据
                    if (data_buffer) free(data_buffer);
                    size_t sample_count;
                    size_t buffer_size;

                    // 根据模式计算采样点数量
                    if (wave_mode == MODE_SINE_ONLY || wave_mode == MODE_TRIANGLE_ONLY) {
                        // 单波形模式: 每个采样点2字节
                        sample_count = total_bytes / 2;
                        // 确保不会生成超出总字节数的数据
                        if (sample_count * 2 > total_bytes) sample_count--;
                    } else {
                        // 交替模式: 每个采样对4字节
                        sample_count = total_bytes / 4;
                        if (sample_count * 4 > total_bytes) sample_count--;
                    }

                    data_buffer = generate_wave_data(sample_count, &buffer_size);
                    // 确保缓冲区大小与计算一致
                    if (data_buffer && buffer_size > total_bytes) {
                        free(data_buffer);
                        data_buffer = NULL;
                        log_message("Generated data exceeds total byte limit");
                    }
                    data_sent = 0;
                    log_message("generated data (mode: %d), total: %zu bytes",
                              wave_mode, buffer_size);
                }
                break;

            case 1:  // 波形选择（单波形模式下有效）
                if (frame_data == WAVE_SINE || frame_data == WAVE_TRIANGLE) {
                    wave_mode = frame_data;  // 1=正弦, 2=三角
                    log_message("waveform selected: %u (%s)", frame_data,
                              frame_data == WAVE_SINE ? "sine wave" : "triangle wave");
                }else if(frame_data == MODE_ALTERNATING)
                {
                    wave_mode = frame_data;  // 3交替
                    log_message("waveform selected:ch1：sine wave; ch2:triangle wave");
                }
                else {
                    log_message("Invalid waveform selection! Please use 1 (sine wave) or 2 (triangle wave)");
                }
                break;

            case 2:  // 总发送字节数设置
                total_bytes = frame_data;
                log_message("Total transmit byte count setting: %u", total_bytes);
                break;

            case 3:  //采样速率设置，本案例因为是模拟产生数据，无需设置采样速率，故此项留空
                break;

            default:
                log_message("Unknown Frame Address: %hhu", frame_addr);
                break;
        }
        pthread_mutex_unlock(&mutex);

        // 移除已处理的帧,调整缓冲区
        buf_len -= frame_start + FRAME_SIZE;
        if (buf_len > 0) {
            memmove(recv_buf, recv_buf + frame_start + FRAME_SIZE, buf_len);
        }
    }
}

// 客户端处理线程
void *handle_client(void *arg) {
    int client_fd = *(int *)arg;
    free(arg);

    // 获取客户端地址信息
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    getpeername(client_fd, (struct sockaddr *)&client_addr, &client_len);
    log_message("New connection: %s:%d", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

    // 更新当前客户端socket
    pthread_mutex_lock(&mutex);
    if (client_socket != -1) {
        close(client_socket);
        log_message("Closed previous connection");
    }
    client_socket = client_fd;
    pthread_mutex_unlock(&mutex);

    // 接收客户端数据
    uint8_t buffer[BUFFER_SIZE];
    ssize_t len;
    while ((len = recv(client_fd, buffer, BUFFER_SIZE, 0)) > 0) {
        log_message("Received data: %zd bytes", len);
        process_received_data(buffer, len);
    }

    // 连接关闭处理
    log_message("Connection closed: %s:%d", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
    pthread_mutex_lock(&mutex);
    if (client_socket == client_fd) {
        client_socket = -1;
        sending_enabled = false;
        if (data_buffer) {
            free(data_buffer);
            data_buffer = NULL;
            data_sent = 0;
        }
    }
    pthread_mutex_unlock(&mutex);

    close(client_fd);
    return NULL;
}

// 信号处理函数
void handle_signal(int sig) {
    log_message("Received exit signal");
    server_running = false;
}

int main() {
    log_message("Waveform TCP server started (supports multiple waveform modes)");
    log_message("Lookup tables loaded: sine wave and triangle wave");

    // 注册信号处理
    signal(SIGINT, handle_signal);
    signal(SIGTERM, handle_signal);

    // 创建发送线程
    if (pthread_create(&send_thread, NULL, send_data_thread, NULL) != 0) {
        perror("Failed to create sending thread");
        return 1;
    }

    // 创建服务器socket
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("Failed to create socket");
        return 1;
    }

    // 设置socket选项
    int opt = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("Failed to set socket options");
        return 1;
    }

    // 绑定地址和端口
    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("Failed to bind port");
        return 1;
    }

    // 监听连接
    if (listen(server_fd, 3) < 0) {
        perror("Failed to listen");
        return 1;
    }

    log_message("Server started successfully, listening on port: %d", PORT);

    // 接受客户端连接
    while (server_running) {
        int *new_socket = malloc(sizeof(int));
        socklen_t addr_len = sizeof(address);
        if ((*new_socket = accept(server_fd, (struct sockaddr *)&address, &addr_len)) < 0) {
            if (server_running) perror("Failed to accept connection");
            free(new_socket);
            break;
        }

        // 创建客户端处理线程
        pthread_t client_thread;
        if (pthread_create(&client_thread, NULL, handle_client, new_socket) != 0) {
            perror("Failed to create client thread");
            close(*new_socket);
            free(new_socket);
        }
        pthread_detach(client_thread);  // 分离线程,自动释放资源
    }

    // 服务器关闭清理
    log_message("Server is shutting down...");
    close(server_fd);
    pthread_mutex_lock(&mutex);
    if (client_socket != -1) {
        close(client_socket);
    }
    if (data_buffer) {
        free(data_buffer);
    }
    pthread_mutex_unlock(&mutex);
    pthread_join(send_thread, NULL);  // 等待发送线程结束
    pthread_mutex_destroy(&mutex);

    log_message("Server has shut down");
    return 0;
}
