#ifndef COMMON_FUNC_HPP_
#define COMMON_FUNC_HPP_
#include <string.h>
#include <sys/statfs.h>
#include <string>
#include <vector>
#include <iostream>
#include <json/json.h>

typedef struct statfs DISK, *pDISK;

#define SECTION_MAX_LEN 1024
#define STRVALUE_MAX_LEN 1024
#define LINE_CONTENT_MAX_LEN 1024
//配置文件位置
#define NETWORK "/etc/network/interfaces"
#define SYSTEMINFOFILE "/opt/configenv/SystemInfo.json" //系统信息
#define SERVERCONFIG "/opt/configenv/ServerConfig.json"
#define NETWORKCONFIG "/opt/configenv/NetWorkConfig.json"
#define SOFTWARE_RUN_LOG "/opt/log/"
#define BOARDTYPE "/opt/configenv/boardtype" //设备类型
#define ZIGBEECONFIG "/opt/configenv/ZigbeeConfig.json"

#define SN "/opt/system/sn"             //设备序列号
#define SYSTEMSTART "/opt/system/start" //系统启动类型标志  0：正常启动  1：重启   2:
#define BUILD_UINT16(x, y) (((x & 0x00FFu) << 8u) | (y & 0x00FFu))
#define BUILD_UINT2(x, y) (((x) << 2u) | (y))
// 生成UINT32 数据
#define BUILD_UINT32(u, v, x, y) (((u & 0x00FFu) << 24u) | (v & 0x00FFu) << 16u) | (((x & 0x00FFu) << 8u) | (y & 0x00FFu))

// 生成UINT64 数据
#define BUILD_UINT48(u, v, x, y, x1, y1) (((u & 0x00FFu) << 40u) | ((u & 0x00FFu) << 32u) | ((x & 0x00FFu) << 24u) | (y & 0x00FFu) << 16u) | (((x1 & 0x00FFu) << 8u) | (y1 & 0x00FFu))

// 获取UINT32的高低字节
#define UINT32_HIGH_1(x) ((x & 0xFF000000u) >> 24u)
#define UINT32_HIGH_2(x) ((x & 0x00FF0000u) >> 16u)
#define UINT32_LOW_1(x) ((x & 0x0000FF00u) >> 8u)
#define UINT32_LOW_2(x) ((x & 0x000000FFu))
#define GET_BIT(x, bit) ((x & (1 << bit)) >> bit) /* 获取第bit位 */
// 获取UINT32的高低字节
#define UINT16_HIGH(x) ((x & 0xFF00u) >> 8u)
#define UINT16_LOW(x) ((x & 0x00FFu))


enum TIME_SIZE { 
	TIME_MINUTE = 5, 
	TIME_SECEOND = 8 
};

struct DevData {
    char mData[128];
    char mDataMing[128];
    int mLen;
    DevData() : mLen(0) {
        memset(mData, 0, 128);
        memset(mDataMing, 0, 128);
    }
};

struct compressWaveChannel {
    int compressChannelX;
    int compressChannelY;
    int compressChannelZ;
    int compressChannelVolX;
    int compressChannelVolY;
    int compressChannelVolZ;
    int CountX;
    int CountY;
    int CountZ;
    int CountVolX;
    int CountVolY;
    int CountVolZ;
    int samplerateX;
    int samplerateY;
    int samplerateZ;
    int samplerateVolX;
    int samplerateVolY;
    int samplerateVolZ;
    compressWaveChannel() {
        compressChannelX = 0;
        compressChannelY = 0;
        compressChannelZ = 0;
        compressChannelVolX = 0;
        compressChannelVolY = 0;
        compressChannelVolZ = 0;
        CountX = 0;
        CountY = 0;
        CountZ = 0;
        CountVolX = 0;
        CountVolY = 0;
        CountVolZ = 0;
        samplerateX = 0;
        samplerateY = 0;
        samplerateZ = 0;
        samplerateVolX = 0;
        samplerateVolY = 0;
        samplerateVolZ = 0;
    }
};
struct WaveChannel {
    std::vector<float> WaveChannelX;
    std::vector<float> WaveChannelY;
    std::vector<float> WaveChannelZ;
    std::string wave_timestamp;
    WaveChannel() {
        WaveChannelX.reserve(25600);
        WaveChannelY.reserve(25600);
        WaveChannelZ.reserve(48000);
    }
};
struct WaveVolChannel {
    std::vector<float> WaveChannelVolX;
    std::vector<float> WaveChannelVolY;
    std::vector<float> WaveChannelVolZ;
    std::string wave_timestamp;
    WaveVolChannel() {
        WaveChannelVolX.reserve(25600);
        WaveChannelVolY.reserve(25600);
        WaveChannelVolZ.reserve(48000);
    }
};
struct DevDataOfGwid {
    std::string mDevdata;
    std::string mDevid;
    bool mIsSimulate;
    DevDataOfGwid() : mDevdata(""), mDevid(""), mIsSimulate(false) {}
};

typedef void (*onReceiveUart)(DevDataOfGwid& devData);

struct sys_data {
    char data[10240];
};


struct ZigbeeInfo {
    int DevMode;
    int Channel;
    std::string PanID;
    std::string MyAddr;
    std::string DstAddr;
    std::string RetryNum;
    std::string TranTimeout;
};

struct ZIGBEE {
    char reserve[4];
    char DevName[16];
    char DevPwd[16];
    unsigned char DevMode;
    unsigned char Chan;
    short PanID;
    short MyAddr;
    unsigned char MyIEEE[8];
    short DstAddr;
    unsigned char DstIEEE[8];
    unsigned char Reserve0;
    unsigned char PowerLevel;
    unsigned char RetryNum;
    unsigned char TranTimeout;
    unsigned char Serial_Rate;
    unsigned char Serial_DataB;
    unsigned char Serial_StopB;
    unsigned char Serial_ParityB;
    unsigned char Reserve[10];
};

struct RecvData {
    unsigned char Head[3];
    unsigned char ShortAddr[2];
    unsigned char Type;
    unsigned char Order;
    unsigned char Data[92];
    unsigned char Crc;
};

struct DataNodeInfo {
    int InitFlag;
    int AccFlag;
    int ZigbeeFlag;
    int TemTopFlag;
    int TemBotFlag;
    int EquipSta; //设备状态
    std::string ZigbeeLongAddr;
    std::string HardVersion;
    std::string SoftVersion;
    std::string BpNo;
    std::string SerialNo;
    std::string FirstPowerTime;
    int WakeupTime;
    int StaticTime;
    int WaveTime;
    int BateryV;
    std::string ProductNo;
    int RSSI; // 接收信号强度
    int ConfigFlag;
    unsigned int FeatureInterVal; //特征值发送时间间隔，单位分钟
    unsigned int WaveInterVal;    //原始数据发送时间间隔，单位分钟
    std::string ZigbeePanId;
    int ZigbeeChannel;
    std::string ZigbeeShortAddr;
    std::string ZigbeeDesAddr;
    int ZigbeePower;
    int ZigbeeRetry;
    int ZigbeeRetryGap;
    int Range;         //量程
    int SamplingRate;  //采样率
    int ACCSampleTime; //采样时间

    std::string StartBrands; //频带能量参数 1,2,3,4,5,START
    std::string StopBrands;  //频带能量参数 1,2,3,4,5,END

    std::string EnvelopeBandPass; //冲击带通频率
    std::string FaultFrequency;   //故障频率1,2,3,4

    std::string ConfigDate;       //配置时间
    int VIntegralFilterFrequency; //速度积分滤波频率
    DataNodeInfo() {
        FeatureInterVal = 0;
        WaveInterVal = 0;
    }
};

typedef struct  {
    float TemTop;
    float TemBot;
    int Dip;
    int Voltage;
    float nodeWorkTime;
    float nodeSendTime;
    int minmumBatteryVoltageType;
    int instantaneousBatteryVoltage;
}DataRecvStatic;

typedef struct  {
    float DiagnosisPk;
    float IntegratPk;
    float IntegratRMS;
    float RmsValues;
    float EnvelopEnergy;
    float Amp1;
    float Amp2;
    float Amp3;
    float Amp4;
    float Amp5;
    long Time;
    float Phase1;
    float Phase2;
    float Phase3;
    float Phase4;
    float kurtosis;
    float IntegratRMSMENS;
}DataRecvDym;

struct TopicList {
    std::string mPubData;   //每秒特征数据上传主题
    std::string mPubStatus; //状态上传主题
    std::string mPubHeart;
    std::string mPubConfig;         //上传配置主题
    std::string mSubData;           //订阅主题
    std::string mPubWaveData;       //原始数据发布主题
    std::string mPubWaveSecondData; //原始数据发布主题
    std::string mPubCmd;            //命令控制发布主题
    std::string mPubRep;
    std::string mPubTiming; //校时

    std::string mPubLocalWifi;
    std::string mPubLocalWaveServer;
    std::string mPubLocalWaveQt;
    std::string mPubLocalTrigger;
    std::string mPubLocalConfig;
    std::string mPubLocalCmd;
};

//系统描述文件数据定义
typedef struct {
    std::string siteID;        // Unique ID for each site
    std::string siteName;      // Controller site name
    std::string siteCountry;   // Controller location country
    std::string siteProvince;  // province
    std::string siteCity;      // city
    double siteLongitude; // longitude
    double siteLatitude;  // latitude
    std::string siteTimeZone;
    std::string plantName; // Unique plant number
    std::string plantNo;
    std::string equipmentName; // Equipment Description in the plant
    std::string equipmentNo;
    std::string dataWatchName;    // DNS Name for the DataWatch
    long dataWachAddedDate;  // Date of settings’ creation (Time Stamp)
    std::string dataWatchAssetID; // Unique equipment Asset ID
    std::string deviceType;
    std::string dataWachAddedBy; // User who edited settings
    std::string serialNumber;
    std::string softVersion;
} SystemInfo;

typedef struct {
    int zigAckrep;
    int zigAckreset;
    int zigReset;
    int zigDef;
    int alarmLight;
    int commPower; // 4G,5G 电源开关
    int vol3_8;    // 5G 3.8v电源
    int commRest;  // 4G,5G复位
    int wifiPower; // WiFi 电源开关
    int wifiReset; // WiFi 复位
    int hardWatchDog;
    int power;
    int runLed;
    int errorLed;
    int netResetNet0;
    int netResetNet1;
} GPIOInfo;

struct DataNodeUpdate {
    std::string strUpdataFileName;
    std::string strSoftVersion;
    std::vector<std::string> hwVersion;
};

struct ethtool_value {
    unsigned int cmd;
    unsigned int data;
};

void hexToAscii(const char* hexStr, char* asciiStr);
void stringToHex(const char* str, char* hexStr);
std::string GetLocalTimeWithMs(void);
int InitGpio(unsigned int gpioN, unsigned int inout);
int gpio_set(unsigned int gpioN, char x);
int gpio_read(unsigned int gpioN);
int config_uart(const char* Port, int speed);
int write_data(int fd, char* buff, int len);
int read_data(int fd, char* buff, int len, int timeout);
int ModifyMac(char* buff);
void mssleep(unsigned long microseconds);

/**
* @brief 获取当前实时时间
* @return 时间string 例：2018-11-18 17:16:10
*/
std::string GetCurrentTime();

tm* get_current_date();
/**
* @brief  和系统交互函数
* @param cmd  要发出的系统命令 例：ls
* @param buf  系统返回的数据存在buf里
* @return -1：失败 0：成功
*/
int system_custom(const char* cmd, char* buf);

/**
* @brief  获取当前时间戳
* @param timebuf 定义的buf存储数据
* @param type 0 是毫秒级的时间戳  1 秒级的时间戳
* @return void
*/
void GetTimeNet(char* timebuf, int type);

std::string GetRTC(char* timebuf, int& millisecond);

/**
* @brief  从配置文件中读取数据
* @param filename 配置文件名
* @param config 配置选项
* @param option 具体配置参数
* @return std::string  返回要获取的参数数据
*/
std::string ReadStrByOpt(std::string filename, std::string config, std::string option);

/**
* @brief  写配置文件
* @param filename 配置文件名
* @param config 配置选项
* @param option 具体配置参数
* @param value 具体的数据值
* @return int  0：配置成功
*/
int WriteStr2Config(std::string filename, std::string config, std::string option, std::string value, bool listable = false);

/**
* @brief  获取设备的MAC地址做为设备的唯一标识
* @return std::string  Mac地址
*/
std::string GetLocalMac(const char* net);

/**
* @brief  获取设备IP
* @return std::string  IP地址
*/
std::string IpAddrInit();

/**
* @brief  设置系统时间
* @return int
*/
int SetTime(unsigned long seconds, int milliseconds = 0);

/**
* @brief  获取文件内容
* @param filename 文件名
* @param line 第几行
* @return std::string
*/
std::string GetFileContent(std::string filename, int line);

/**
* @brief 配置时区
* @param zoneid 时区ID
* @return void
*/
void ZoneConfig(std::string zoneid);

/**
* @brief  获取系统基本信息
* @return std::string  CPU MEM DISK info
*/
std::string GetSysStatus(Json::Value &jsData);
void GetSysStatusCMT(int& cpu_use,int& mem_use,int& disk_remain,int& cpu_temp);
bool CheckIP(const char* ip);

bool IsValidMask(std::string mask);
// read update config file
std::vector<DataNodeUpdate> ReadStrUpdate(std::string filename);

void ReadStrConfig(std::string filename);
void ImportConfig(std::string filename);
int UpdataDataNodeConfig(std::string filename);
char* solve(char* dest, const char* src);
void swap(char* data);
int hexStringToBytes(const char* hexStr, unsigned char* bytes, size_t bytesSize);
void int2bytes(int i, unsigned char *bytes, int size);
int OpenWatchDog();
int WriteWatchDog(int fd);

std::string GetGwIp_(const char* eth_name);
std::string GetOneContent(const char* szData, int nRow, const char* szSeparate);
int readStringValue(const char* section, const char* key, char* val, const char* file);
int writeStringVlaue(const char* section, const char* key, char* val, const char* file);
int readIntValue(const char* section, const char* key, const char* file);
int writeIntValue(const char* section, const char* key, int val, const char* file);

int getDiskInfo(char* diskTotal, char* diskFree);

unsigned short cal_chksum(unsigned short* addr, int len);

int socketHeart(const char* pSendData);

int Ping(const char* ips, int timeout);
int get_netlink_status(const char* if_name);
int compareVersions(const std::string& version1, const std::string& version2);
void Binary_Bit(unsigned char* p_data, unsigned char position, int flag);
std::string get_file_md5(const std::string& file_path);
#endif // COMMON_FUNC_HPP_
