#ifdef STM32

#include <stdbool.h>
#undef bool
#undef true
#undef false

#include "lwip/opt.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "lwip/sys.h"
#include "lwip/inet.h"

#include "net_eth_stm32.h"
#include "agent_log.h"
#include "net_interface.h"
#include <string.h>

#define bool   bool_xxl
#define true   true_xxl
#define false  false_xxl

#define RECV_BUF_SIZE 2048

// ==========================================================================
// ✅ 每个TCP连接独立结构体（支持多客户端，无全局变量）
// ==========================================================================
typedef struct {
    uint8_t buf[RECV_BUF_SIZE];
    uint32_t len;
    bool_xxl is_connected;  // 🔥 每个连接独立的连接完成标志
} tcp_recv_buf_t;

// 增加外部声明
extern void lwip_periodic_handle(void);
extern int ip4addr_aton(const char *cp, ip_addr_t *addr);

void net_eth_stm32_loop(void)
{
    // 🔥 必须调用，否则TCP无法握手、收发包
    lwip_periodic_handle();
}


__attribute__((weak)) void eth_socket_set_init(void)
{
}

__attribute__((weak)) void eth_socket_set_add(int sock)
{
}

__attribute__((weak)) void eth_socket_set_remove(int sock)
{
}

__attribute__((weak)) void eth_set_mqtt_tcp_socket(PlatformSocket tcp_sock)
{
}

// ==========================================================================
// TCP 实现（已完成）
// ==========================================================================
static err_t tcp_recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    tcp_recv_buf_t *rx = (tcp_recv_buf_t*)arg;

    if (p == NULL) {
        tcp_close(pcb);
        return ERR_OK;
    }

    // ✅ 修复：增加有效长度判断
    if (rx != NULL && p->tot_len > 0 && p->tot_len < RECV_BUF_SIZE) {
        memcpy(rx->buf, p->payload, p->tot_len);
        rx->len = p->tot_len;
    }

    tcp_recved(pcb, p->tot_len);
    pbuf_free(p);
    return ERR_OK;
}

// ==========================================================================
// ✅ TCP 连接完成回调（真正三次握手完成！）
// ==========================================================================
static err_t tcp_connect_cb(void *arg, struct tcp_pcb *pcb, err_t err)
{
    tcp_recv_buf_t *rx = (tcp_recv_buf_t*)arg;

    if (err == ERR_OK && rx != NULL) {
        rx->is_connected = true_xxl;  // 🔥 独立标志，不影响多客户端
        agent_log_info("[STM32] TCP 连接已就绪");
    }

    return ERR_OK;
}

// ==========================================================================
// 创建 TCP socket
// ==========================================================================
PlatformSocket net_tcp_socket_create_stm32(void)
{
    struct tcp_pcb *pcb = tcp_new();
    if (!pcb) {
        agent_log_error("[STM32] TCP create failed");
        return PLATFORM_SOCKET_INVALID;
    }

    tcp_recv_buf_t *rx = mem_malloc(sizeof(tcp_recv_buf_t));
    if (!rx) {
        tcp_close(pcb);
        return PLATFORM_SOCKET_INVALID;
    }
    memset(rx, 0, sizeof(tcp_recv_buf_t));

    tcp_arg(pcb, rx);
    tcp_recv(pcb, tcp_recv_callback);

    agent_log_info("[STM32] TCP socket created");
    return (PlatformSocket)pcb;
}

// ==========================================================================
// TCP 连接
// ==========================================================================
bool_xxl net_tcp_connect_stm32(PlatformSocket sock, const char* ip, uint16_xxl port)
{
    struct tcp_pcb *pcb = (struct tcp_pcb *)sock;
    ip_addr_t dest_ip;

    if (!pcb || ip4addr_aton(ip, &dest_ip) == 0) {
        return false_xxl;
    }

    // 修复：传入回调，不能为 NULL
    if (tcp_connect(pcb, &dest_ip, port, tcp_connect_cb) != ERR_OK) {
        return false_xxl;
    }

    agent_log_info("[STM32] TCP connecting to %s:%d", ip, port);
    return true_xxl;
}

// ==========================================================================
// ✅【终极正确】TCP 发送（等待当前连接真正就绪，支持多客户端）
// ==========================================================================
int32_xxl net_tcp_send_stm32(PlatformSocket sock, const uint8_xxl* data, uint32_xxl len)
{
    struct tcp_pcb *pcb = (struct tcp_pcb *)sock;
    tcp_recv_buf_t *rx = (tcp_recv_buf_t*)pcb->callback_arg;

    if (!pcb || !rx || !data || len == 0) return -1;

    // 🔥 等待当前TCP连接真正完成（独立等待，互不影响）
    uint32_t timeout = 0;
    while (rx->is_connected == false_xxl && timeout < 3000) {
        lwip_periodic_handle();
        platform_delay_ms(1);
        timeout++;
    }

    if (!rx->is_connected) {
        agent_log_error("[STM32] 连接未就绪");
        return -1;
    }

    // 发送
    err_t err = tcp_write(pcb, data, len, TCP_WRITE_FLAG_COPY);
    tcp_output(pcb);

    if (err == ERR_OK || err == ERR_INPROGRESS) {
        return len;
    }

    agent_log_error("[STM32] send failed: %d", err);
    return -1;
}

// ==========================================================================
// TCP 接收
// ==========================================================================
int32_xxl net_tcp_recv_stm32(PlatformSocket sock, uint8_xxl* buf, uint32_xxl max_len, uint32_xxl timeout_ms)
{
    struct tcp_pcb *pcb = (struct tcp_pcb *)sock;
    tcp_recv_buf_t *rx = (tcp_recv_buf_t*)pcb->callback_arg;

    if (!pcb || !rx || !buf || max_len == 0) return 0;
    if (rx->len == 0) return 0;

    uint32_t copy_len = (rx->len > max_len) ? max_len : rx->len;
    memcpy(buf, rx->buf, copy_len);
    rx->len = 0;

    return copy_len;
}

// ==========================================================================
// TCP 关闭
// ==========================================================================
void net_socket_close_stm32(PlatformSocket sock)
{
    struct tcp_pcb *pcb = (struct tcp_pcb *)sock;
    if (!pcb) return;

    tcp_recv_buf_t *rx = (tcp_recv_buf_t*)pcb->callback_arg;
    if (rx) {
        mem_free(rx);
    }

    tcp_close(pcb);
    agent_log_info("[STM32] socket closed");
}

NetErr net_eth_stm32_init(void)
{
    return NET_OK;
}

// ==========================================================================
// UDP 空实现（未来支持 MQTT@UDP 使用）
// ==========================================================================
PlatformSocket net_udp_socket_create_stm32(void)
{
    // 未来替换为 lwip udp_new()
    agent_log_info("[STM32] UDP create OK");
    return 1;
}

bool_xxl net_udp_bind_stm32(PlatformSocket sock, uint16_xxl port)
{
    // 未来替换为 udp_bind()
    return true_xxl;
}

int32_xxl net_udp_sendto_stm32(PlatformSocket sock, const char* ip, uint16_xxl port, const uint8_xxl* data, uint32_xxl len)
{
    // 未来实现 udp_sendto()
    return -1;
}

int32_xxl net_udp_recvfrom_stm32(PlatformSocket sock, uint8_xxl* buf, uint32_xxl max_len,
                                 char* src_ip, uint16_xxl* src_port, uint32_xxl timeout_ms)
{
    // 未来实现 udp_recvfrom()
    return 0;
}

#endif
