/**
 * @file tcp_client.h
 * @brief Indexed lwIP RAW TCP client manager.
 */

#ifndef __TCP_CLIENT_H__
#define __TCP_CLIENT_H__

#include <stdbool.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define TCP_CLIENT_INSTANCE_COUNT      2u
#define TCP_CLIENT_RX_BUFFER_SIZE      480u
#define TCP_CLIENT_RECONNECT_DELAY_MS  3000u
#define TCP_CLIENT_CONNECT_TIMEOUT_MS  10000u

typedef enum {
    TCP_CLIENT_STATE_IDLE = 0,
    TCP_CLIENT_STATE_CONNECTING,
    TCP_CLIENT_STATE_CONNECTED,
    TCP_CLIENT_STATE_DISCONNECTED,
    TCP_CLIENT_STATE_ERROR
} tcp_client_state_t;

typedef struct {
    uint8_t remote_ip[4];
    uint16_t local_port;
    uint16_t remote_port;
    uint16_t reconnect_interval_ms;
    bool enabled;
    bool auto_reconnect;
} tcp_client_instance_config_t;

typedef struct {
    tcp_client_state_t state;
    uint32_t rx_bytes;
    uint32_t tx_bytes;
    uint32_t reconnect_count;
    uint32_t connect_timeout_count;
    uint32_t errors;
} tcp_client_status_t;

int tcp_client_init_all(void);
int tcp_client_config(uint8_t instance, const tcp_client_instance_config_t *config);
int tcp_client_connect(uint8_t instance);
int tcp_client_disconnect(uint8_t instance);
int tcp_client_send(uint8_t instance, const uint8_t *data, uint16_t len);
int tcp_client_recv(uint8_t instance, uint8_t *data, uint16_t max_len);
uint16_t tcp_client_rx_available(uint8_t instance);
uint16_t tcp_client_peek(uint8_t instance, uint8_t *data, uint16_t max_len);
void tcp_client_drop(uint8_t instance, uint16_t len);
bool tcp_client_is_connected(uint8_t instance);
void tcp_client_get_status(uint8_t instance, tcp_client_status_t *status);
void tcp_client_poll(void);

#ifdef __cplusplus
}
#endif

#endif /* __TCP_CLIENT_H__ */
