#ifndef INTERFACE_H
#define INTERFACE_H
///////////////////////////////////////////////////////////////////////////////////////////

#include <string>
#include <list>
#include <array>
#include <map>
#include <mutex>

///////////////////////////////////////////////////////////////////////////////////////////

#include "nlohmann/json.hpp"

#include "../../client2.h"

///////////////////////////////////////////////////////////////////////////////////////////

class Front;

///////////////////////////////////////////////////////////////////////////////////////////

/*#define STAT_DATA_BASE_NODE_ID			100
#define THREE_SECS_DATA_BASE_NODE_ID	200
#define SOE_COMTRADE_BASE_NODE_ID		300
#define HIS_DATA_BASE_NODE_ID			400
#define NEW_HIS_DATA_BASE_NODE_ID		500
#define RECALL_HIS_DATA_BASE_NODE_ID	600
#define RECALL_ALL_DATA_BASE_NODE_ID	700*/

///////////////////////////////////////////////////////////////////////////////////////////

//单条补招结构
class RecallInfo
{
public:
	long long starttime;//开始时间
	long long endtime;	//结束时间
};

//日志补招结构类
class JournalRecall 
{
public:
	std::string MonitorID; //线路监测点号
	std::string StartTime; //数据补招起始时间
	std::string EndTime;   //数据补招结束时间
	std::string STEADY;    //补招历史统计数据标识 0-不补招；1-补招     
	std::string VOLTAGE;   //补招暂态事件标识     0-不补招；1-补招
};

//监测点台账
class ledger_monitor 
{
public:
	std::string monitor_id;			//监测点id
    std::string terminal_id;		//监测点
    std::string monitor_name;		//监测点名
    std::string logical_device_seq;	//监测点序号
    std::string voltage_level;		//监测点电压等级
    std::string terminal_connect;	//监测点接线方式
    std::string timestamp;			//更新时间
	std::string status;				//监测点状态

    double PT1;                 // 电压变比1
    double PT2;                 // 电压变比2
    double CT1;                 // 电流变比1
    double CT2;                 // 电流变比2
};

//终端台账
class terminal_dev 
{
public:
    std::string guid;   //台账更新回复用

	std::string terminal_id;
    std::string terminal_name;
    std::string org_name;
    std::string maint_name;
    std::string station_name;
    std::string tmnl_factory;
    std::string tmnl_status;
    std::string dev_type;
    std::string dev_key;
    std::string dev_series;
    std::string addr_str;
    std::string port;
    std::string timestamp;
	std::string processNo;
	std::string maxProcessNum;

    std::string mac;            // 装置MAC地址

    std::vector<ledger_monitor> line;
};

//icd模型
class icd_model 
{
public:
	std::string model_id;		//模型id
    std::string tmnl_type;		//终端类型
	std::string tmnl_type_id;	//终端类型id
    std::string tmnl_factory;	//终端厂家
    std::string file_name;		//文件名
	std::string file_path;		//文件路径
    std::string updatetime;		//更新时间

    icd_model() = default;
};

class queue_data_t //发送数据结构类
{ 
public: 
	int				monitor_no;		   //监测点排号
	std::string		strTopic;		   //发送topic
	std::string		strText;		   //发送的json字符串
	std::string	    mp_id;             //监测点id
}; 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// SOE 事件类
class CEventData {
public:
    int nDataType;                 // 告警 SOE 事件类型
    std::string type;              // 参数等级 type 类型
    std::string triggerFlag;       // 告警触发指标名称
    int nIndex;                    // 数据在每条线路值数组中的位置
    std::string DO;                // 数据对象名
    std::string DA;                // 数据属性名
    std::string strFullName;       // 数据对象名 $ 数据属性名
};

// 数据值类
class CDataValue {
public:
    std::string strName;           // 数据名
    float fValue;                  // 数据值
    bool bIsValue;                 // 数据是否赋值成功标识
    int nIndex;                    // 数据在每条线路值数组中的位置
    std::string type;              // 参数等级 type 类型
    std::string DO;                // 数据对象名
    std::string DA;                // 数据属性名
    std::string strFullName;       // 数据对象名 $ 数据属性名
    std::string strCoefficient;    // 数据系数(字符型)
    float fCoefficient;            // 数据系数(浮点型)
    std::string strOffset;         // 起始序号偏移量(字符型)
    int iOffset;                   // 起始序号偏移量(整型)
    bool bIsAngle;                 // 角度标志
    bool bPlt;                     // 长时闪变标识：true-长时闪变 false-短时闪变
    std::string BaseFlag;          // 历史数据部分新增指标 BaseFlag
    std::string LimitUp;           // 历史数据部分新增指标 LimitUp
    std::string LimitDown;         // 历史数据部分新增指标 LimitDown

    CDataValue()
        : fValue(0.0f), bIsValue(false), nIndex(0),
          fCoefficient(1.0f), iOffset(0), bIsAngle(false), bPlt(false) {}
};

// 相别(A、B、C、T)类
class CSequence {
public:
    std::string strSValue;         // 相别值 例：7：ABC三项，8：T相，112：AB、BC、CA三项
    std::string strSeq;            // 相别 例：A、B、C、T
    std::string type;              // 参数等级 type 类型
    std::list<CDataValue*> DataValueList; // 数据值链表
};

// 数据项类
class CItem {
public:
    std::string strItemName;       // 数据项名
    std::string strItemValue;      // 数据项值
    std::string type;              // 参数等级 type 类型
    std::list<CSequence*> SequenceList; // 相别列表
};

// 监测点类
class CMonitor {
public:
    std::string strMonitor;        // 监测点名
    std::string type;              // 参数等级 type 类型
    std::list<CItem*> ItemList;    // 数据项链表
};

// 数据类型类
class CDataType {
public:
    int iDataType;                      // 数据类型值：1-稳态 2-闪变 3-暂态
    std::string type;                   // 参数等级 type 类型
    int BaseFlag1;                      // 记录基础数据总个数
    int BaseFlag0;                      // 记录非基础数据个数
    std::list<CMonitor*> MonitorList;   // 监测点列表
    std::list<CEventData*> SOEList;     // 暂态事件列表

    CDataType() : iDataType(0), BaseFlag1(0), BaseFlag0(0) {}
};

// 队列生产者发送主题类
class CTopic {
public:
    std::string strTopic;               // 队列生产者发送的主题名
    std::list<CDataType*> DataTypeList; // 数据类型链表
};

///////////////////////////////////////////////////////////////////////////////////////////////

// XML 解析配置类
class XmlConfig {
public:
    std::string WavePhasicFlag;    // 是否分相 0-不分相 1-分相
    std::string WavePhasicA;
    std::string WavePhasicB;
    std::string WavePhasicC;
    std::string UnitOfTimeUnit;     // 暂态事件持续单位：0-毫秒 1-秒
    std::string ValueOfTimeUnit;    // 上送值时间：UTC 或 北京时间
    std::string WaveTimeFlag;       // 录波文件时间：UTC 或 北京时间
    std::string IEDname;            // 例：PQMonitor
    std::string LDevicePrefix;      // 例：PQM
    std::list<CEventData*> SOEList; // SOE 告警事件链表
};

// 数据库模型表数据类
class XmlDataBase {
public:
    std::string MODEL_ID;          // 模型编码 GUID
    std::string TMNL_TYPE;         // 终端型号
    std::string TMNL_FACTORY;      // 终端厂家
    std::string FILE_PATH;         // 远端模型文件路径
    std::string FILE_NAME;         // 远端文件名
    std::string updatetime;        // 更新时间
};

class Xmldata
{
public:
	XmlDataBase xmlbase;        //模型数据
	XmlConfig xmlcfg;           //icd映射文件解析数据
	std::list<CTopic*> topicList;    //队列发送主题链表
	bool updataflag = true;     //更新标志
};

////////////////////////////////////////////////////////////////////////////////////////////////////////

//台账更新结构/////////////////////////////////////////////
#define MAX_UPDATEA_NUM 10
typedef struct trigger_update_xml_t trigger_update_xml_t;
struct trigger_update_xml_t {
    std::vector<terminal_dev> new_updates;
    std::vector<terminal_dev> modify_updates;
    std::vector<terminal_dev> delete_updates;
    std::vector<terminal_dev> work_updates;

    trigger_update_xml_t() = default;
};

//实时触发结构////////////////////////////////////////////////////////
#define MAX_TRIGGER_NUM 300
typedef struct trigger_t trigger_t;
struct trigger_t{
	int dev_idx;
	int line_id;
	int real_data;
	int soe_data;
	int limit;
	int count;
};
typedef struct trigger_3s_xml_t trigger_3s_xml_t;
struct trigger_3s_xml_t{
	int			work_trigger_num;
	int			new_trigger_num;
	int			delete_trigger_num;
	int			modify_trigger_num;
	trigger_t	work_triggers[MAX_TRIGGER_NUM];
	trigger_t	new_triggers[MAX_TRIGGER_NUM];
	trigger_t	delete_triggers[MAX_TRIGGER_NUM];
	trigger_t	modify_triggers[MAX_TRIGGER_NUM];
};

//补招触发结构//////////////////////////////////////////////////////////
#define MAX_RECALL_NUM 300
typedef struct recall_t recall_t;
struct recall_t{ 
	std::string     line_id;
	long long		start_time;	 //待召唤日志起始时间
	long long		end_time;	 //待召唤日志结束时间
	int need_steady;
	int need_voltage; 
};
typedef struct recall_xml_t recall_xml_t;
struct recall_xml_t{
	int			work_recall_num;
	int			new_recall_num; 
	recall_t	work_recalls[MAX_RECALL_NUM];
	recall_t	new_recalls[MAX_RECALL_NUM]; 
};

///////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////interface的函数声明

std::string parse_model_cfg_web_one(const std::string& terminal_type);

int parse_device_cfg_web();
int parse_model_cfg_web();

void qvvr_test();
void Fileupload_test();

extern std::vector<terminal_dev> terminal_devlist;
extern std::mutex ledgermtx;

//////////////////////////////////////////////////////////////////////////////////cfg_parse的函数声明

void init_config();
void Set_xml_nodeinfo();
void Set_xml_nodeinfo_one(const std::string& dev_type);

void check_3s_config();
void check_ledger_update();
void create_recall_xml();

double sGetMsTime();
std::string get_current_time();

bool is_blank(const std::string& str);

void print_terminal(const terminal_dev& tmnl);
void printTerminalDevMap(const std::map<std::string, terminal_dev>& terminal_dev_map);

void upload_data_test();

////////////////////////////////////////////////////////////////////////////////mq

extern std::mutex queue_data_list_mutex;
extern std::list<queue_data_t> queue_data_list;

/////////////////////////////////////////////////////////////////////////////////主函数类声明

//std::string get_front_msg_from_subdir();

extern std::string FRONT_PATH;
extern int g_front_seg_index;
extern int g_front_seg_num;

void* cloudfrontthread(void* arg);
bool parse_param(int argc, char* argv[]);

struct ThreadArgs {
    int argc;
    char **argv;
};

//////////////////////////////////////////////////////////////////////////////////主要架构

/* 常量定义 */
#define THREAD_CONNECTIONS 10        // 最大线程数
#define MONITOR_INTERVAL 1           // 监控间隔(秒)

/* 线程状态枚举 */
typedef enum {
    THREAD_RUNNING,     // 0:运行中
    THREAD_STOPPED,     // 1:正常停止  
    THREAD_RESTARTING,  // 2:重启中
    THREAD_CRASHED      // 3:异常崩溃
} thread_state_t;

/* 线程控制结构体 */
typedef struct {
    pthread_t tid;          // 线程ID
    int index;              // 线程编号(0~CONNECTIONS-1)
    thread_state_t state;   // 当前状态
    pthread_mutex_t lock;   // 线程专用互斥锁
} thread_info_t;

///////////////////////////////////////////////////////////////////////////////////////上送数据的json格式
// 单条 DataArray 数据
struct DataArrayItem {
    int DataAttr;
    int DataTimeSec;
    int DataTimeUSec;
    int DataTag;
    std::string Data;
};

// Msg 对象
struct MsgObj {
    int Cldid;
    int DataType;
    int DataAttr;
    int DsNameIdx;
    std::vector<DataArrayItem> DataArray;
};

// 整体
struct FullObj {
    int Mid;
    int Did;
    int Pri;
    int Type;
    MsgObj Msg;
};

// nlohmann序列化接口
void to_json(nlohmann::json& j, const DataArrayItem& d);
void to_json(nlohmann::json& j, const MsgObj& m);
void to_json(nlohmann::json& j, const FullObj& f);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////提供给通讯部分调用的函数

std::vector<DeviceInfo> GenerateDeviceInfoFromLedger(const std::vector<terminal_dev>& terminal_devlist);//接口读取台账后，再调用这个将台账拷贝过来

std::string generate_json(  //构造装置主动上送数据的报文
    int Mid,    //需应答的报文订阅者收到后需以此ID应答，无需应答填入“-1”
    int Did,    //设备唯一标识Ldid，填入0代表Ndid。
    int Pri,    //报文处理的优先级
    int Type,   //消息类型
    int Cldid,  //逻辑子设备ID，0-逻辑设备本身，无填-1
    int DataType,   //数据类型，0-表示以数据集方式上送
    int DataAttr,   //数据属性：无“0”、实时“1”、统计“2”等。
    int DsNameIdx,  //数据集序号（以数据集方式上送），无填-1
    const std::vector<DataArrayItem>& dataArray     //数据数组。
);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#endif


