#ifndef __COMMON_H
#define __COMMON_H

#include <netinet/in.h>
#include <sys/socket.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/socket.h>

#include "lnxall_list.h"
#include "mqtt_session.h"
#include "dy_utils/dy_common.h"

#define MAXEPOLLSIZE 10000
#define LISTEN_BACKLOG 10

#define HASH_SIZE 1024

#define FRONT_CFG "/app/config/socket_mqtt.json"

#define NAPI_QUEUE_LEN  64
#define WAIT_TIME_SECONDS 1
#define CONNECT_CHECK_INTERVAL  3            //网络连接检查间隔，秒为单位
#define MAX_MQTT_CHANNEL_CNT  8

#define FRONT_LOG  "/app/socket_mqtt.log"

static inline int socket_hash(int socket) {
    return socket & (HASH_SIZE -1);
}

static inline int hash_string(const char* s)
{
    unsigned long h = 0;
    for ( ; *s; ++s)
        h = 5 * h + *s;
    return h & (HASH_SIZE -1);
}

typedef struct socket_data_node_s {
    struct list_head list;
    int socket; // 本机socket
	uint16_t payload_len;
    uint8_t payload[0];
} socket_data_node_t;

typedef struct sock_sess_node_s {
    struct hlist_node sock_hash_list;
    struct hlist_node sn_hash_list;
    int socket;
    char sn[SN_MAX_LEN];
    mqtt_session_t *mqtt;
} sock_sess_node_t;

typedef struct sock_sn_sess_table_s {
    struct hlist_head sock_sess_hash[HASH_SIZE];
    struct hlist_head sn_sess_hash[HASH_SIZE];
} sock_sn_sess_table_t;

typedef struct socket_mqtt_var_s {
    int mqtt_cnt;
    mqtt_session_t* mqtt[MAX_MQTT_CHANNEL_CNT]; // MQTT session, used to forward the TCP/UDP socket data to broker
    char sn_str[SN_MAX_LEN];
    int tcp_port;
    int udp_port;
    sock_sn_sess_table_t *sock_sn_sess_table;
    struct list_head socket_rcv_head;
    pthread_rwlock_t sock_sess_lock;
    pthread_mutex_t socket_data_lock;
    pthread_cond_t socket_recv_cond;
    int socket_received;
} socket_mqtt_var_t;

extern socket_mqtt_var_t socket_mqtt_var;
extern void* start_tcp_server(void *param);
extern void* mqtt_forward_loop(void *param);
extern void* socket_forward_loop(void *param);
extern int mqtt_init(socket_mqtt_var_t *var);
extern sock_sess_node_t* find_session_by_socket(int socket);
extern sock_sess_node_t *delete_session_by_socket(int socket);
extern sock_sess_node_t* find_session_by_sn(const char * const sn);
extern sock_sess_node_t *find_session_by_sn_nolock(const char *const sn);
extern int add_session(sock_sess_node_t *sess);
extern int del_session(sock_sess_node_t *sess);
extern int del_session_nolock(sock_sess_node_t *sess);
extern int add_session_nolock(sock_sess_node_t *sess);
extern int mqtt_handle_sync_sn(mqtt_session_t *mqtt, mqtt_message_t *mqtt_msg);
extern void mqtt_connect_timer(socket_mqtt_var_t *var);
extern ssize_t socket_send(int sockfd, const char* buffer, size_t buflen);

#endif
