#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <strings.h>
#include <time.h>
#include <unistd.h>

#include "comm_uart.h"
#include "myLog.h"

static void uart_sleep(int ticks)
{
    struct timespec rqtp;
    struct timespec rmtp;

    rqtp.tv_sec = ticks / 1000;
    rqtp.tv_nsec = (ticks % 1000) * 1000000L;
    
    while (nanosleep(&rqtp, &rmtp) == -1 && errno == EINTR)
    {
        rqtp = rmtp;
    }
}

static int uart_state_register(void *p_this, comm_state_cb cb)
{
    if(NULL == p_this || NULL == cb)
    {
        LOG_E("p_this or cb is null");
        return -1;
    }
    stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
    p_uart->state_cb = cb;

    return 0;
}

static int uart_debug_show_register(void *p_this, comm_debug_show_cb cb)
{
    if(NULL == p_this || NULL == cb)
    {
        LOG_E("p_this or cb is null");
        return -1;
    }
    stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
    p_uart->debug_show_cb = cb;

    return 0;
}

static int uart_recv_register(void *p_this, comm_recv_cb cb)
{
    if(NULL == p_this || NULL == cb)
    {   
        LOG_E("p_this or cb is null");
        return -1;
    }
    stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
    p_uart->recv_cb = cb;

    return 0;
}


static int uart_create(stru_comm_uart *p_uart)
{
    if(NULL == p_uart)
    {
        LOG_E("uart is null");
        return -1;
    }

    p_uart->uart_fd = open(p_uart->p_para->device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
    if (p_uart->uart_fd < 0) {
        LOG_E("open %s failed\r\n", p_uart->p_para->device.c_str());
        return -1;
    }

    struct termios newtio, oldtio;

    if(0 != tcgetattr(p_uart->uart_fd, &oldtio))
    {
        LOG_E("tcgetattr failed !\n");
        return (-1);
    }

    bzero(&newtio, sizeof(newtio));

    newtio.c_cflag |= CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;

    switch(p_uart->p_para->baudrate)
    {
        case 600:
            cfsetispeed(&newtio, B600);
            cfsetospeed(&newtio, B600);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 1200:
            cfsetispeed(&newtio, B1200);
            cfsetospeed(&newtio, B1200);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 2400:
            cfsetispeed(&newtio, B2400);
            cfsetospeed(&newtio, B2400);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 4800:
            cfsetispeed(&newtio, B4800);
            cfsetospeed(&newtio, B4800);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 9600:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 19200:
            cfsetispeed(&newtio, B19200);
            cfsetospeed(&newtio, B19200);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 38400:
            cfsetispeed(&newtio, B38400);
            cfsetospeed(&newtio, B38400);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 57600:
            cfsetispeed(&newtio, B57600);
            cfsetospeed(&newtio, B57600);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 115200:
            cfsetispeed(&newtio, B115200);
            cfsetospeed(&newtio, B115200);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 500000:
            cfsetispeed(&newtio, B500000);
            cfsetospeed(&newtio, B500000);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 1000000:
            cfsetispeed(&newtio, B1000000);
            cfsetospeed(&newtio, B1000000);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        case 2500000:
            cfsetispeed(&newtio, B2500000);
            cfsetospeed(&newtio, B2500000);
            LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
            break;
        default:
            cfsetispeed(&newtio, B115200);
            cfsetospeed(&newtio, B115200);
            LOG_I("default baudrate = %d\n", 115200);
            break;
    }

    switch(p_uart->p_para->data_bits)
    {
        case 7:
            newtio.c_cflag |= CS7;
            break;
        case 8:
            newtio.c_cflag |= CS8;
            break;
        default:
            newtio.c_cflag |= CS8;
            break;
    }

    switch(p_uart->p_para->stop_bits)
    {
        case 1:
            newtio.c_cflag &= ~CSTOPB;
            break;
        case 2:
            newtio.c_cflag |= CSTOPB;
            break;
        default:
            newtio.c_cflag &= ~CSTOPB;
            break;
    }

    switch(p_uart->p_para->parity)
    {
        case 'n':
        case 'N':
            newtio.c_cflag &= ~PARENB; // Clear parity enable
            newtio.c_iflag &= ~INPCK; // Enable parity checking
            break;
        case 'o':
        case 'O':
            newtio.c_cflag |= (PARODD | PARENB); // 设置为奇校验
            newtio.c_iflag |= INPCK; // Enable parity checking
            break;
        case 'e':
        case 'E':
            newtio.c_cflag |= PARENB; // Enable parity
            newtio.c_cflag &= ~PARODD; // 设置为偶校验
            newtio.c_iflag |= INPCK; // Enable parity checking
            break;
        default:
            newtio.c_cflag &= ~PARENB; // Clear parity enable
            newtio.c_iflag &= ~INPCK; // Enable parity checking
            break;
    }

    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 0;

    tcflush(p_uart->uart_fd, TCIFLUSH);

    if((tcsetattr(p_uart->uart_fd, TCSANOW, &newtio)) != 0) 
    {
        LOG_E("tcsetattr failed !\n");
        return (-1);
    }

    LOG_I("tcsetattr success ! %s, %d, %d, %d, %c\n", 
        p_uart->p_para->device.c_str(), p_uart->p_para->baudrate, p_uart->p_para->data_bits, 
        p_uart->p_para->stop_bits, p_uart->p_para->parity);
    return (0);
}


static int uart_connect(int id,  void *p_this)
{
    if(NULL == p_this)
    {
        LOG_E("p_this is null");
        return -1;
    }

    stru_comm_uart *p_uart = (stru_comm_uart *)p_this;

    if(0 != uart_create(p_uart))
    {
        LOG_E("uart_create failed");
        return -1;
    }

    if(p_uart->state_cb)
    {
        p_uart->state_cb(id, p_uart->uart_fd, CommState::connected);
    }

    uint8_t rx_buffer[1024];
    while (1)
    {
        int len = read(p_uart->uart_fd, rx_buffer, sizeof(rx_buffer));
        if(len > 0)
        {
            if(p_uart->recv_cb)
            {
                p_uart->recv_cb(id, p_uart->uart_fd, rx_buffer, len);
            }
            else
            {
                LOG_E("recv_cb is null");
            }

            if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
            {
                p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_recv, rx_buffer, len);
            }
        }
        uart_sleep(10);
    }

    return 0;
}

static int uart_send(void *p_this, const uint8_t *tx, uint16_t tx_len)
{
    stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
    if(NULL == p_uart)
    {
        LOG_E("p_uart is null");
        return -1;
    }

    if(NULL == tx || tx_len <= 0)
    {
        LOG_E("tx is null or len is invalid");
        return -1;
    }

    int ret = write(p_uart->uart_fd, tx, tx_len);
    if(ret < 0)
    {
        LOG_E("write failed");
        return -1;
    }

    if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
    {
        p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_send, tx, tx_len);
    }

    return 0;
}

static int uart_close(void *p_this)
{
    if(NULL == p_this)
    {
        LOG_E("p_this is null");
        return -1;
    }

    stru_comm_uart *p_uart = (stru_comm_uart *)p_this;

    if(p_uart->uart_fd < 0)
    {
        LOG_E("uart_fd is invalid");
        return -1;
    }

    close(p_uart->uart_fd);
    p_uart->uart_fd = -1;

    if(p_uart->state_cb)
    {
        p_uart->state_cb(0, p_uart->uart_fd, CommState::disconnected);
    }

    return 0;
}

int comm_uart_create(stru_comm_uart *p_uart)
{
    if(NULL == p_uart)
    {
        LOG_E("uart is null");
        return -1;
    }

    p_uart->uart_fd = -1;

    p_uart->uart_state_register = uart_state_register;
    p_uart->uart_debug_show_register = uart_debug_show_register;
    p_uart->uart_recv_register = uart_recv_register;

    p_uart->uart_connect = uart_connect;

    p_uart->uart_send = uart_send;

    p_uart->uart_close = uart_close;

    return 0;
}


// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <termios.h>
// #include <fcntl.h>
// #include <sys/ioctl.h>
// #include <sys/stat.h>
// #include <strings.h>
// #include <time.h>
// #include <unistd.h>
// #include <errno.h>

// #include "comm_uart.h"
// #include "myLog.h"

// // 20ms 帧超时判断
// #define FRAME_IDLE_TIMEOUT_MS  10
// // 接收缓冲区最大长度
// #define UART_MAX_FRAME_LEN     4096

// static void uart_sleep(int ticks)
// {
//     struct timespec rqtp;
//     struct timespec rmtp;

//     rqtp.tv_sec = ticks / 1000;
//     rqtp.tv_nsec = (ticks % 1000) * 1000000L;
    
//     while (nanosleep(&rqtp, &rmtp) == -1 && errno == EINTR)
//     {
//         rqtp = rmtp;
//     }
// }

// // 获取当前时间 ms
// static long long get_current_ms(void)
// {
//     struct timespec ts;
//     clock_gettime(CLOCK_MONOTONIC, &ts);
//     return ts.tv_sec * 1000LL + ts.tv_nsec / 1000000;
// }

// static int uart_state_register(void *p_this, comm_state_cb cb)
// {
//     if(NULL == p_this || NULL == cb)
//     {
//         LOG_E("p_this or cb is null");
//         return -1;
//     }
//     stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
//     p_uart->state_cb = cb;
//     return 0;
// }

// static int uart_debug_show_register(void *p_this, comm_debug_show_cb cb)
// {
//     if(NULL == p_this || NULL == cb)
//     {
//         LOG_E("p_this or cb is null");
//         return -1;
//     }
//     stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
//     p_uart->debug_show_cb = cb;
//     return 0;
// }

// static int uart_recv_register(void *p_this, comm_recv_cb cb)
// {
//     if(NULL == p_this || NULL == cb)
//     {   
//         LOG_E("p_this or cb is null");
//         return -1;
//     }
//     stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
//     p_uart->recv_cb = cb;
//     return 0;
// }

// static int uart_create(stru_comm_uart *p_uart)
// {
//     if(NULL == p_uart)
//     {
//         LOG_E("uart is null");
//         return -1;
//     }

//     p_uart->uart_fd = open(p_uart->p_para->device.c_str(), O_RDWR | O_NOCTTY);
//     if (p_uart->uart_fd < 0) {
//         LOG_E("open %s failed\r\n", p_uart->p_para->device.c_str());
//         return -1;
//     }

//     struct termios newtio;
//     if(0 != tcgetattr(p_uart->uart_fd, &newtio))
//     {
//         LOG_E("tcgetattr failed !\n");
//         close(p_uart->uart_fd);
//         p_uart->uart_fd = -1;
//         return -1;
//     }

//     bzero(&newtio, sizeof(newtio));
//     newtio.c_cflag |= CLOCAL | CREAD;
//     newtio.c_cflag &= ~CSIZE;

//     // 波特率配置（保留你原来的）
//     switch(p_uart->p_para->baudrate)
//     {
//         case 600:cfsetispeed(&newtio, B600);cfsetospeed(&newtio, B600);break;
//         case 1200:cfsetispeed(&newtio, B1200);cfsetospeed(&newtio, B1200);break;
//         case 2400:cfsetispeed(&newtio, B2400);cfsetospeed(&newtio, B2400);break;
//         case 4800:cfsetispeed(&newtio, B4800);cfsetospeed(&newtio, B4800);break;
//         case 9600:cfsetispeed(&newtio, B9600);cfsetospeed(&newtio, B9600);break;
//         case 19200:cfsetispeed(&newtio, B19200);cfsetospeed(&newtio, B19200);break;
//         case 38400:cfsetispeed(&newtio, B38400);cfsetospeed(&newtio, B38400);break;
//         case 57600:cfsetispeed(&newtio, B57600);cfsetospeed(&newtio, B57600);break;
//         case 115200:cfsetispeed(&newtio, B115200);cfsetospeed(&newtio, B115200);break;
//         case 500000:cfsetispeed(&newtio, B500000);cfsetospeed(&newtio, B500000);break;
//         case 1000000:cfsetispeed(&newtio, B1000000);cfsetospeed(&newtio, B1000000);break;
//         case 2500000:cfsetispeed(&newtio, B2500000);cfsetospeed(&newtio, B2500000);break;
//         default:cfsetispeed(&newtio, B115200);cfsetospeed(&newtio, B115200);break;
//     }

//     // 数据位
//     switch(p_uart->p_para->data_bits)
//     {
//         case 7: newtio.c_cflag |= CS7; break;
//         case 8: newtio.c_cflag |= CS8; break;
//         default: newtio.c_cflag |= CS8; break;
//     }

//     // 停止位
//     switch(p_uart->p_para->stop_bits)
//     {
//         case 1: newtio.c_cflag &= ~CSTOPB; break;
//         case 2: newtio.c_cflag |= CSTOPB; break;
//         default: newtio.c_cflag &= ~CSTOPB; break;
//     }

//     // 校验位
//     switch(p_uart->p_para->parity)
//     {
//         case 'n':case 'N':
//             newtio.c_cflag &= ~PARENB;
//             newtio.c_iflag &= ~INPCK;
//             break;
//         case 'o':case 'O':
//             newtio.c_cflag |= (PARODD | PARENB);
//             newtio.c_iflag |= INPCK;
//             break;
//         case 'e':case 'E':
//             newtio.c_cflag |= PARENB;
//             newtio.c_cflag &= ~PARODD;
//             newtio.c_iflag |= INPCK;
//             break;
//         default:
//             newtio.c_cflag &= ~PARENB;
//             newtio.c_iflag &= ~INPCK;
//             break;
//     }

//     // 原始模式 + 超时设置
//     newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//     newtio.c_oflag &= ~OPOST;
//     newtio.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | INLCR | IGNCR);

//     // ===================== 关键：串口读取超时 =====================
//     newtio.c_cc[VTIME] = 1;    // 读超时 100ms
//     newtio.c_cc[VMIN]  = 0;    // 最小读取 0 字节

//     tcflush(p_uart->uart_fd, TCIFLUSH);
//     if((tcsetattr(p_uart->uart_fd, TCSANOW, &newtio)) != 0) 
//     {
//         LOG_E("tcsetattr failed !\n");
//         close(p_uart->uart_fd);
//         p_uart->uart_fd = -1;
//         return -1;
//     }

//     LOG_I("uart init success: %s, %d, %d, %d, %c\n", 
//         p_uart->p_para->device.c_str(), p_uart->p_para->baudrate,
//         p_uart->p_para->data_bits, p_uart->p_para->stop_bits, p_uart->p_para->parity);
//     return 0;
// }

// // ===================== 核心：超时分帧接收 =====================
// static int uart_connect(int id, void *p_this)
// {
//     if(NULL == p_this)
//     {
//         LOG_E("p_this is null");
//         return -1;
//     }

//     stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
//     if(0 != uart_create(p_uart))
//     {
//         LOG_E("uart_create failed");
//         return -1;
//     }

//     if(p_uart->state_cb)
//         p_uart->state_cb(id, p_uart->uart_fd, CommState::connected);

//     // 动态帧缓冲区
//     uint8_t *frame_buf = (uint8_t *)malloc(UART_MAX_FRAME_LEN);
//     if(!frame_buf)
//     {
//         LOG_E("malloc failed");
//         return -1;
//     }

//     int frame_len = 0;
//     long long last_recv_ms = get_current_ms();

//     uint8_t read_buf[1024];
//     while (1)
//     {
//         int len = read(p_uart->uart_fd, read_buf, sizeof(read_buf));
//         if(len > 0)
//         {
//             if(p_uart->recv_cb)
//                 p_uart->recv_cb(id, p_uart->uart_fd, read_buf, len);

//             if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
//                 p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_recv, read_buf, len);
//         }

//         uart_sleep(10); 
//         // if(len > 0)
//         // {
//         //     // 收到数据，拼帧
//         //     if(frame_len + len < UART_MAX_FRAME_LEN)
//         //     {
//         //         memcpy(frame_buf + frame_len, read_buf, len);
//         //         frame_len += len;
//         //         last_recv_ms = get_current_ms();
//         //     }
//         //     else
//         //     {
//         //         LOG_E("frame overflow, reset");
//         //         frame_len = 0;
//         //     }
//         // }
//         // else if(len == 0)
//         // {
//         //     // 超时，判断是否满足 20ms 空闲
//         //     long long now = get_current_ms();
//         //     if(frame_len > 0 && (now - last_recv_ms >= FRAME_IDLE_TIMEOUT_MS))
//         //     {
//         //         // ===================== 一帧接收完成 =====================
//         //         if(p_uart->recv_cb)
//         //             p_uart->recv_cb(id, p_uart->uart_fd, frame_buf, frame_len);

//         //         if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
//         //             p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_recv, frame_buf, frame_len);

//         //         frame_len = 0; // 重置
//         //     }
//         //     uart_sleep(1); // 小延时降低 CPU
//         // }
//         // else
//         // {
//         //     uart_sleep(1);
//         // }
//     }

//     free(frame_buf);
//     return 0;
// }

// static int uart_send(void *p_this, const uint8_t *tx, uint16_t tx_len)
// {
//     stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
//     if(NULL == p_uart || NULL == tx || tx_len <= 0)
//     {
//         return -1;
//     }

//     int ret = write(p_uart->uart_fd, tx, tx_len);
//     if(ret < 0)
//     {
//         LOG_E("write failed");
//         return -1;
//     }

//     if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
//     {
//         p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_send, tx, tx_len);
//     }
//     return 0;
// }

// static int uart_close(void *p_this)
// {
//     if(NULL == p_this)
//     {
//         LOG_E("p_this is null");
//         return -1;
//     }

//     stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
//     if(p_uart->uart_fd >= 0)
//     {
//         close(p_uart->uart_fd);
//         p_uart->uart_fd = -1;
//     }

//     if(p_uart->state_cb)
//     {
//         p_uart->state_cb(0, p_uart->uart_fd, CommState::disconnected);
//     }
//     return 0;
// }

// int comm_uart_create(stru_comm_uart *p_uart)
// {
//     if(NULL == p_uart)
//     {
//         LOG_E("uart is null");
//         return -1;
//     }

//     p_uart->uart_fd = -1;
//     p_uart->uart_state_register = uart_state_register;
//     p_uart->uart_debug_show_register = uart_debug_show_register;
//     p_uart->uart_recv_register = uart_recv_register;
//     p_uart->uart_connect = uart_connect;
//     p_uart->uart_send = uart_send;
//     p_uart->uart_close = uart_close;
//     return 0;
// }