#ifndef _GREE_INFO_H_
#define _GREE_INFO_H_

// LINUX端模拟使用
// #include <netinet/in.h>
// 板子使用
#include <sys/socket.h>
// 通用
#include <stdbool.h>
#include <stdio.h>
#include <pthread.h>
#include "lwip/sockets.h"

#define USE_CACHE 1

//使用缓存策略
#if USE_CACHE
#include "gree_cache.h"
#endif


#define GREE_OK                      0        /**< int value indicating success (no error) */
#define GREE_FAIL                    -1       /**< Generic int code indicating failure */
#define GREE_ERR_INVALID_ARG         -2       /**< Invalid argument */
#define GREE_CONTINUE                1        /**< 需要继续判断 */

#define HOME_UDP_VER 1

#define HOME_HID "362001071025+ZTS31B3V1.102.img"
#define HOME_VER "V3.2.MF"
#define HOME_MID "70502_01"

#define DEV_MAX_NUMBER                1000
#define ROOM_MAX_NUMBER               200

#define HOST_MAC_LENGTH 16 //主机mac长度为16位
#define HOST_KEY_LENGTH 16 //主机key长度为16位
#define HOST_GNETKEY_LENGTH 8 //GNet key长度为8位

typedef enum 
{
    DEV_TYPE_NONE = 0, /**< 待定 */
    DEV_TYPE_CAN,  /**< CAN多联机设备 */
    DEV_TYPE_485,  /**< 485设备 */
    DEV_TYPE_UDP,  /**< UDP小家电设备 */
    DEV_TYPE_FASTCON,  /**< Fastcon设备 */
    DEV_TYPE_MINIPRO,  /**< 小程序 */
    DEV_TYPE_CENTCTRL,  /**< 中控设备 */
    DEV_TYPE_HOST,  /**< 主机设备 */
    DEV_TYPE_PWRGATEWAY, /**能源网关设备 */
    DEV_TYPE_GATEWAY, /**网关设备 */
    DEV_TYPE_BLE, /**BLE设备*/
    DEV_TYPE_WIFI, /**WIFI设备*/
    DEV_TYPE_OPGATEWAY, /**欧普网关*/
    DEV_TYPE_OPDEV, /**欧普设备*/
    DEV_TYPE_MJGATEWAY,/**美景网关*/
    DEV_TYPE_MAX,   //分割
    DEV_TYPE_GROUP_UDP_CENTCTRL=50, /**组合类型：UDP+中控 */
    DEV_TYPE_GROUP_CAN_485 = 51,    /**组合类型：CAN+485 */
    DEV_TYPE_GROUP_UDP_CENTCTRL_GW=52, /**组合类型：UDP+中控+网关 */
    DEV_TYPE_SPECIAL_LINE = 69,/**特定设备类型： 分界线*/
    DEV_TYPE_CURTAINER = 70, /**特定设备类型：窗帘 70501*/
    DEV_TYPE_ALL_MAX,
} dev_type_t;

#define GREE_SOCKET_INVALID_FD  -1

typedef enum 
{
    SOCKET_CONNECT_TYPE_NONE, /**< Unknown connection method */
    SOCKET_CONNECT_TYPE_TCP,  /**< Transfer data using a TCP connection */
    SOCKET_CONNECT_TYPE_UDP,  /**< Transfer data using a UDP connection */
    SOCKET_CONNECT_TYPE_BROADCAST,  /**< Transfer data using a BROADCAST connection */
    SOCKET_CONNECT_TYPE_MULTICAST,  /**< Transfer data using a MULTICAST connection */
    SOCKET_CONNECT_TYPE_MQTT,
    SOCKET_CONNECT_TYPE_HTTP,
    SOCKET_CONNECT_TYPE_UDS,
    SOCKET_CONNECT_TYPE_BLE,
} connect_type_t;

//群控设备类型
typedef enum 
{
    G_CTRL_TYPE_NONE,
    G_CTRL_TYPE_SWITCH = 3,     //开关
    G_CTRL_TYPE_CENTRL = 5,     //中控
    G_CTRL_TYPE_CURTAIN = 7,    //窗帘
    G_CTRL_TYPE_LIGHT = 8,      //灯
    G_CTRL_TYPE_FAN = 9,        //风扇
    G_CTRL_TYPE_AC = 10,        //空调
} group_ctrl_t;

//设备品类类型
typedef enum {
    DEV_CLASS_TYPE_NONE,
    DEV_CLASS_TYPE_SWITCH = 3,     //开关
    DEV_CLASS_TYPE_CENTRL = 5,     //中控
    DEV_CLASS_TYPE_CURTAIN = 7,    //窗帘
    DEV_CLASS_TYPE_LIGHT = 8,      //灯
    DEV_CLASS_TYPE_FAN = 9,        //风扇
    DEV_CLASS_TYPE_AC = 10,        //空调
    DEV_CLASS_TYPE_MAX = 11,       
} dev_class_t;


//房间信息结构体类型
typedef struct roomItem_s
{
	unsigned int id;    		//房间云ID
    unsigned int sId;   		//房间本地房间ID
    char name[128];				//房间名
	struct roomItem_s *next;	//下一个房间
} roomItem_t;

//房间信息列表
typedef struct roomInfoList_s
{
	int roomNumbers;			//房间数量
	roomItem_t *roomInfo;		//房间信息
    pthread_mutex_t rwlock;    //房间信息列表读写锁

} roomInfoList_t;


//设备注册状态
typedef enum {
    F_UNREGISTER, //未注册设备
    F_REGISTERED, //已注册设备
    F_RELEASE,    //待释放设备
} register_flag_t;

//设备通信信息结构体
typedef struct 
{
    int fd;                             //连接句柄
    struct sockaddr_in ip_addr;         //连接ip
    connect_type_t type;                //连接类型
    void *ctx;                          //上下文
} dev_socket_t;

//扩展字段数据类型
typedef enum
{
	EXT_DATA_TYPE_DEFAULT,
	EXT_DATA_TYPE_NUMBER,
	EXT_DATA_TYPE_STRING,
	EXT_DATA_TYPE_JSON,
} ext_data_t;

//扩展字段结构体类型
typedef struct
{
	ext_data_t type;
	unsigned int dataLen;
	void* data;
} dataExt_t;

typedef struct 
{
    uint32_t state  : 2;   // 状态：0=离线, 1=在线, 2=暂停
    uint32_t ticks  : 30;  // 心跳计数（最多10亿+，足够用）
} heartbeat_t;



//设备信息结构体
typedef struct devInfo_s
{
    char mac[16 + 1];								//设备MAC
    char mid[15 + 1];								//设备MID
    unsigned int macId;								//设备短地址
    dev_type_t dev_type;							//设备类型
    dev_socket_t dev_socket;						//设备通信符
    unsigned int roomId;    						//本地房间ID
    unsigned char scene;      						//是否需要下发默认场景
    char key[16 + 1];								//设备密钥
    int RSSI;										//设备信号强度
    heartbeat_t hb;							        //设备心跳 
	register_flag_t f_register;  					//设备注册状态
    unsigned long updateTs;							//更新时间戳
//缓存数据
    char pmac[16 + 1];								//主设备mac
    char hid[40];									//设备固件版本信息
    char ver[16];									//设备通信协议版本
    char vender[16];								//厂家id					
    char name[128];									//设备名称
    char noteName[128];							//设备别名
    char* dataBuf;									//设备数据缓冲区
	unsigned int dataBufSize;						//设备数据缓冲区大小
	unsigned char f_hidden;							//设备隐藏标识	
	char* bindTime;								    //绑定时间
    dataExt_t *devExt;   							//用于存放设备的扩展信息。
	
    struct devInfo_s *next;							//下一个设备信息
} devInfo_t;


//设备信息列表
typedef struct devInfoList_s
{
	int devInfoNumbers;			//设备信息数量
	devInfo_t *devInfo;			//设备信息
    pthread_mutex_t rwlock;     //设备信息列表读写锁
} devInfoList_t;

//配网状态类型
typedef enum
{
	F_UNMATCH = 0,		//未配网
	F_MATCHING,			//配网中
	F_MATCHED,			//已配网
	F_REMATCH,			//再次配网
} match_flag_t;

//场景任务结构体类型
typedef struct
{
	char mac[17];			//目标设备MAC
	char subId[17];			
	char extraId[16];
	char remark[16];
	char *dat;
	int delayTime;
	int localizedCtrl;
	char *thirdId;
	int secGroupNum;
	int sId;
	int pId;
	int opt;
} scene_task_t;

//场景扩展任务结构体类型
typedef struct
{
	char devName[128];
	int roomId;
	char notInHomeReason;
	char sceneName[128];		//场景名称
} scene_taskExt_t;

//场景任务状态结构体类型
typedef struct
{
	char *result;			//执行结果
	int status;				//执行状态
	char stateDes[32];		//执行状态描述
	char startTime[24];		//开始执行时间
} scene_taskSta_t;

//场景项结构体类型
typedef struct sceneItem_s
{
	struct sceneItem_s* next;		//下一个场景项节点
	char id[8];						//场景项ID
	int type;						//场景项类型
	int secNum;						
	scene_task_t task;				//场景项任务
	scene_taskExt_t taskExt;		//场景项扩展任务
	scene_taskSta_t taskStatus;		//场景项任务状态
	char *cmd;						//场景项执行指令
	int subSceneFackId;				//场景项本地id
} sceneItem_t;

//场景项列表结构体类型
typedef struct
{
	sceneItem_t *sceneItem;
	char cTime[20];				//创建时间
	char f_local;				//本地场景标志
	int	fakeId;					//
	int delay;					//延迟时间
	int sceneItemCount;			//场景项总数
} sceneItemList_t;

//场景信息结构体类型
typedef struct scene_info_s
{
	int sceneId;				//场景云ID
	int sceneSid;				//场景本地ID
	char sceneName[128];		//场景名称
	char cTime[20];				//创建时间
	int	tag;					//标签
	char f_abnormal;			//中断标志
	int	homeSort;				
	char f_loop;				//循环标志
	int	roomId;					//所属房间云ID
	int fakeId4NoDelay;			
	unsigned long sceneTag;		//场景标签
	int sceneItemCount;			//场景项总数
	sceneItem_t *sceneItemList;	//场景项列表
	struct scene_info_s *next;	//下一个场景信息
} scene_info_t;

//场景列表
typedef struct
{
	int scene_count;					//场景数量
	scene_info_t *scene_list_head;		//场景链表头部
	scene_info_t *scene_list_tail;		//场景链表尾部
    pthread_mutex_t rwlock;             //场景列表读写锁

} scene_info_list_t;



//家庭信息结构体
typedef struct
{
	char homeMac[17];								//虚拟主机mac
	char homeKey[17];								//虚拟主机密钥
    // char mid[15 + 1];							//虚拟主机MID （可以使用宏定义）
    // char hid[40];								//虚拟主机固件版本信息（可以使用宏定义）
    // char ver[16];								//虚拟主机通信协议版本（可以使用宏定义）
    char Gnetkey[8 + 1];							//Gnet密钥
    unsigned int homeId;            				//家庭ID
    unsigned int devCnt;							//设备总数
    roomInfoList_t roomlist;						//房间列表
#if USE_CACHE
    unified_cache_manager_t devInfoMgr;    			//设备管理器
#else
    devInfoList_t subDevList;    					//设备列表
#endif
    scene_info_list_t sceneList;                    //场景列表
    char province[64];								//省份
    char city[64];									//城市
    char lng[64];									//经度
    char lat[64];									//纬度
    char ssid[128];									//wifi账号
    char wifiPsw[128];								//wifi密码
    char APIDomain[64];								//API接口
	char dishost[33];								//调度服务器
    char nluhost[33];								//语音服务器
	unsigned int disPort;						    //调度服务器端口
    unsigned int nluPort;						    //语音服务器端口
	char isActived;									//是否授权
	char isTimeSync;								//是否同步时间
	match_flag_t f_match;							//配网状态
	unsigned long updateTs;							//更新时间戳
} gree_hostInfo_t;

#endif