/*
 * @Author: ybzhou yibo.zhou@lnxall.com
 * @Date: 2025-07-16 12:38:54
 * @LastEditors: ybzhou yibo.zhou@lnxall.com
 * @LastEditTime: 2025-11-21 17:20:26
 * @FilePath: /2025.07.09/proto_forward/src/automatic_north/north_automatic.h
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#ifndef __NORTH_AUTOMATIC_H__
#define __NORTH_AUTOMATIC_H__

#include <libintl.h>
#include <locale.h>
#include "xlsxwriter_compat.h"
#include "base_tag_sort.h"

#include "../ems/main.h"
#include "../ems/emsctrlProc.h"
#include "../ems/deviceLayer.h"

extern char *ems_compatible[];
extern char *pcs_compatible[];
extern char *bms_compatible[];
extern char *cell_compatible[];
extern char *dido_compatible[];
extern char *ac_compatible[];
extern char *tms_compatible[];
extern char *pv_compatible[];
extern char *dg_compatible[];
extern char *fire_compatible[];
extern char *others_compatible[];
extern char *pcs_meter_compatible[];
extern char *grid_meter_compatible[];
extern char *tras_lv_meter_compatible[];
extern char *load_meter_compatible[];
extern char *pv_meter_compatible[];
extern char *dg_meter_compatible[];
extern char *other_meter_compatible[];

extern char *xlsx_data_type[];

//地址分段
#define IEC104_RP_RESERVE 500
#define IEC104_RM_RESERVE 300
#define IEC104_RC_RESERVE 20
#define IEC104_RR_RESERVE 500

#define MODBUS_RESERVE 500

#define SPECIAL_LIMIT 32 
#define SORT_LIMIT 1000      // 预留固定点位界限最大支持1000个
#define DEV_BETWEEN_ROW 10  // xlsx表设备间距

#define ITEM_NUM (1024 + 1024)
#define SHEET_DEV_NUM 64
#define XLSX_SHEET_NUM 32

#define SHEET_NAME_LEN 64
#define BOOK_NAME_LEN 128
#define TOTAL_MAX_TAG_NUM 10000
#define TAG_NUM (1024 + 2048)
#define DEV_NUM 64
#define CLASS_NUM 32 //最大支持32个类

#define CLASS_NAME_LEN 64
#define DEV_TAG_NAME_LEN 128 // 设备点位名称长度
#define NORTH_CONFIG_PATH "/app/config/north"
#define NORTH_EXCEL_FILE_DOWNLOAD_PATH "/opt/elect_resources/resources/app/web/dist/exdata"

#define DEV_ADDR_INFO_FILE "dev_addr_info.json"
#define TAG_ORDER_FILE "tag_order.json"

#define N_TYPE_MQTT "mqtt"
#define N_TYPE_MODBUSTCP "modbustcp"
#define N_TYPE_IEC104 "iec104"

#define LOG_FLAG 0   // 遍历查找log使能开关

#define _(string) gettext(string)

#define FREE_AND_NULL(ptr)                                   \
    do                                                       \
    {                                                        \
        if (ptr != NULL)                                     \
        {                                                    \
            free(ptr);                                       \
            (ptr) = NULL;                                    \
        }                                                    \
    } while (0)


typedef struct {
	 char no[DEV_NO_LEN];
	 unsigned short addr;
	 unsigned short section_indx;
} dev_cache_info_t;

// 点位顺序信息结构
typedef struct {
    char tag_name[TAG_NAME_LEN];  // 点位名称
    char dev_no[DEV_NO_LEN];      // 设备编号
    char dev_type[CLASS_NAME_LEN]; // 设备类型
    int address;  // 点位地址
    int active;   // 点位是否有效（0有效，1无效）
    int protocol_type; // 协议类型
} tag_order_t;

typedef struct {
	char **compatible;
	const char *name;
	unsigned short num;
	dev_cache_info_t *ptr[DEV_NUM];
} class_name_t;

typedef struct {
     const char *name;
     const int s_addr;
	 const int e_addr;
	 const char *dec;
} home_page_t;

typedef enum
{
    N_PROTOCOL_TYPE_NONE = 0,
    N_PROTOCOL_TYPE_MQTT,     
    N_PROTOCOL_TYPE_MODBUS_TCP, 
    N_PROTOCOL_TYPE_IEC104,  
    N_PROTOCOL_TYPE_MAX, 
} n_protocol_type_t;

typedef struct
{
	char name[TAG_NAME_LEN];
	char dev_tag_name[TAG_NAME_LEN + DEV_NO_LEN];
	char disp_name[TAG_NAME_LEN];
	int data_type;
	int property;
	double scale;
	int active;
	int limit; //读写属性 limit == 1?"RW":"RO"
	void *desc;
	void *proto_ptr;
} mq_xlsx_item_t;

typedef struct
{
    char no[DEV_NO_LEN];
    char disp_name[DEV_NAME_LEN];
	void *proto_ptr;
	int num;
	mq_xlsx_item_t *mq_xlsx_item[ITEM_NUM];
} mq_xlsx_dev_t;

typedef struct
{
    lxw_worksheet *worksheet;
	char name[SHEET_NAME_LEN];
	int cuurent_row;
	int num;
	mq_xlsx_dev_t *mq_xlsx_dev[SHEET_DEV_NUM];
} mq_xlsx_sheet_t;

typedef struct
{
    lxw_workbook  *workbook;
	char name[BOOK_NAME_LEN];
	int num;
	mq_xlsx_sheet_t *mq_xlsx_sheet[XLSX_SHEET_NUM];
} mq_xlsx_book_t;

typedef struct mq_north_tag
{
	tag_t* tag;
	void *ptr;
    void*  proto_ptr;
    int    limit;
    double  coefficient;
} mq_north_tag_t;

typedef struct
{
    char no[DEV_NO_LEN];
    char disp_name[DEV_NAME_LEN];
	char *dev_type;      //设备类型
	char *dev_child_type;//子类 目前有 电表的子类 PCS GRID  没有判断NULL
	char *class_type;
	void *proto_ptr;
	void *ptr;
	int num;
	mq_north_tag_t *mq_north_tag[TAG_NUM]; // 所有设备前128个点留做固定点区域

	tag_t fix_tags[SORT_LIMIT + SPECIAL_LIMIT]; // 固定点区域
} mq_north_dev_t;

typedef struct
{    
	char *class_type; //类 类型 -->xlsx的表
	char name[CLASS_NAME_LEN];
	void *proto_ptr;
	int num;
	mq_north_dev_t *mq_north_dev[DEV_NUM];
} mq_north_class_t;

typedef struct
{   
	int num;
	mq_north_class_t *mq_north_class[CLASS_NUM];
} mq_north_inside_t;

typedef struct
{
	mq_xlsx_book_t *mq_xlsx_book;
	mq_north_inside_t *mq_north_inside;
	mq_north_tag_sort_list* mq_north_tag_sort_list;
} mq_north_info_t;

typedef struct
{
    n_protocol_type_t protocol_type;
	mq_north_info_t mq_north_info;
	int exist;                                 // dev_addr_info.json  0 不存在 1存在（记录地址及偏移）
	int tag_order_exist;                       // tag_order.json  0 不存在 1存在（记录点位顺序）
	int language;
	int need_add_version;                      // Whether to add version field, 1: need, 0: not need
    tag_order_t *tag_order_list;               // 点位顺序列表
    int tag_order_count;                       // 点位顺序数量
} north_info_t;

typedef struct {
     const char* name;
     int index;
	 char *(*handler)(mq_north_inside_t *mq_north_inside, mq_xlsx_book_t *mq_xlsx_book);
} ProtoHandler;

typedef struct {
	mq_north_tag_t *mq_north_tag;
	mq_north_dev_t *mq_north_dev;
} tag_entry_t;

extern class_name_t _class_name[];
char **external_match_by_class_type(char *class_type);

int check_dir(void);
int check_file_exist(char *file_name);
int file_exists(const char *file_path);
int check_json_version(const char *file_path);

north_info_t *get_north_info(void);
int create_north_cfg(int pro, char *data_tmp);
int create_monitor_north_connect_status_task(void);

int get_sys_language(void);

#endif
