#ifndef VIDESDATA_H
#define VIDESDATA_H

#include "XNetSDKDefine.h"
#include<QString>
#include <QProcess>
#include <QDate>
#include <QProcess>
#include <QRegularExpression>
#include <QFile>
#include <QTextStream>
#include <QByteArray> 
#include <QNetworkInterface>
#include <iostream>
#include <cstdio>
#include <string>
#include <sstream>
#include <list>
namespace vides_data{
constexpr const char *HEADER_TYPE_KAY="Content-Type";
constexpr const char *HEADER_TYPE_VALUE="application/json";
constexpr const char *PROFLIE_TEST= "test";
constexpr const char *PROFLIE_DEV= "dev";

struct response
{
    int code;
    void* data;
    QString msg;
    response() {}
};

struct requestCameraInfo{
    
    QString ip_addr;
    QString firmware_version;
    QString sSn;
    requestCameraInfo() {}
};

struct requestDeviceStatus
{
    QString sSn;
    int8_t type;
    int8_t status;
    QString ip_addr;
    QString firmware_version;
    std::list<requestCameraInfo>camera_info_list;
    requestDeviceStatus() {}
};


struct responseStsCredentials{
    QString access_key_id;
    QString access_key_secret;
    QString bucket;
    QString endpoint;
    QString expiration;
    QString security_token;
};
struct responseGb28181 {
    QString sip_ip;
    int sip_port;
    QString serial;
    QString realm;
    QString username;
    QString password;
    int register_validity;
    int heartbeat_interval;
    QString device_id;
    QString channel_id;
};
struct responseArea {
    float bottom_right_corner_x;
    float bottom_right_corner_y;
    float bottom_left_corner_x;
    float bottom_left_corner_y;
    
    float top_left_corner_x;
    float top_left_corner_y;
    float top_right_corner_x;
    float top_right_corner_y;
};
struct responseDeviceStatus
{
    QString sSn;
    int8_t type;
    int8_t merchant_id;
    bool is_reboot;
    std::list<responseArea>areas;
    responseDeviceStatus() : is_reboot(false) {}
};
struct responseDeviceData{
    int algorithm ;
    std::list<responseDeviceStatus> list;
    responseStsCredentials sts_credentials;
};

struct localDeviceStatus
{
    QString sSn;
    int8_t type;
    int8_t merchant_id;
    SXSDK_IPAddress HostIP;
    int HttpPort;
    int TCPPort;
    int ChannelNum;
    QString UserName;
    QString password;
    localDeviceStatus() {}
};
struct requestFaceReconition
{
    QString id;
    QByteArray  img;
    QString sn;
    qint64 time;
    responseArea area;
    requestFaceReconition() {}
};

struct faceRecognitionResult
{
    QString id;
    uint32_t x;
    uint32_t y;
    uint32_t width;
    uint32_t height;
    faceRecognitionResult() {}
};
struct responseFaceReconition
{
    QString id;
    QString  img;
    responseFaceReconition() {}
};
struct ParkingArea
{
    float topLeftCornerX;
    float topLeftCornerY;
    float bottomLeftCornerX;
    float bottomLeftCornerY;
    float bottomRightCornerX;
    float bottomRightCornerY;
    float topRightCornerX;
    float topRightCornerY;
    ParkingArea() {}
};
struct LicensePlate
{
    ParkingArea areaLocation;
    QString new_plate;
    QString new_color;
    QByteArray  img;
    qint64 time;
    ParkingArea recognition;//识别区域
    float text_confidence;
    LicensePlate() {}
};

struct requestLicensePlate
{  
    QString sn;
    std::list<LicensePlate> plates;
    requestLicensePlate() {}
};

struct cameraParameters
{
    QString sDevId;
    int nDevPort;
    QString sUserName;
    QString sPassword;
    int channel;
    QString httpUrl;
    QString sSn;
    QString rtspUrl;
    QString rtmpUrl;
    cameraParameters() {}
};
struct NetWorkNetCommon {
    char* GateWay;        // 网关IP
    char* HostIP;         // 主机IP
    char* HostName;       // 主机名
    int HttpPort;           // HTTP服务端口
    char* MAC;            // MAC地址
    int MaxBps;             // 限定码流值
    char* MonMode;        // 监视协议 {"TCP","UDP","MCAST",…}
    int SSLPort;            // SSL侦听端口
    char* Submask;        // 子网掩码
    int TCPMaxConn;         // 最大连接数
    int TCPPort;            // TCP侦听端口
    char* TransferPlan;   // 传输策略"AutoAdapt":自适应, "Quality":质量优先, "Fluency":流量优先，"Transmission":网传优先
    int UDPPort;            // UDP侦听端口
    bool UseHSDownLoad;     // 是否启用高速录像下载
};


struct responseRecognitionData
{
    int id;
    qint64 inTime;
    qint64 outTime;
    int recognitionType;
    QString sn;
};

struct MainFormat {
    bool AudioEnable;
    int BitRate;
    QString BitRateControl;
    QString Compression;
    int FPS;
    int GOP;
    int Quality;
    QString Resolution;
    int VirtualGOP;
    bool VideoEnable;
    quint64 updateAt;
};

struct ExtraFormat {
    bool AudioEnable;
    int BitRate;
    QString BitRateControl;
    QString Compression;
    int FPS;
    int GOP;
    int Quality;
    QString Resolution;
    int VirtualGOP;
    bool VideoEnable;
    quint64 updateAt;
    
};

struct TimerSettings {
    int deleteLogFileTimer;
    int devicePermissionSynTimer;
    quint64 updateAt;
};
struct Camera {
    int devSnapSynTimer;
    int imageSave;
    QString password;
    QString username;
    float heightReference;
    quint64 updateAt;
};
struct FaceConfig {
    bool isOn;
    int faceNumbers;
    uint64 faceFrequency;
    float confidence;
    int faceLen;
    quint64 updateAt;
};

struct LicensePlateConfig {
    bool isOn;
    float carConfidenceMax;
    float carConfidenceMin;
    int licensePlateLen;
    quint64 updateAt;   
    int maxNum;                                    ///< 识别最大数量
    bool useHalf;                                  ///< 是否使用半精度推理模式
    float boxConfThreshold;                        ///< 检测框阈值
    float nmsThreshold;                             ///< 非极大值抑制阈值
    float recConfidenceThreshold;                   ///< 识别置信度阈值
    bool isHigh;
};


struct UniformConfig {
    bool isOn;
    int uniformColor;
    int humanDetectionLen;
    float carShapeConfidence;
    quint64 updateAt;
    
};
struct HumanConfig{
    bool isOn;
    int humanDetectionLen;
    quint64 updateAt;
};

struct MqttConfig {
    QString address;
    QString clientId;
    int qos;
    quint64 timeout;
    QString topic;
    QString username;
    QString password;
    quint64 updateAt;
};

struct responseConfig {
    MainFormat mainFormat;
    ExtraFormat extraFormat;
    TimerSettings timerSettings;
    FaceConfig faceConfig;
    LicensePlateConfig licensePlateConfig;
    UniformConfig uniformConfig;
    Camera camera;
    MqttConfig mqttConfig;
    
    HumanConfig humanConfig;
};

struct responseMqttData{
    uint8_t msg_type;
    QString sn;
    QString uniq;
};

struct requestMqttData{
    QString sn;
    int code;
    QString uniq;
};
struct DetectionParams {
    int newHumanDetectionLen;
    int newLicensePlateLen;
    int newFaceLen;
    QString modelPaths;
    float humanCarShapeConfidence;
    int uniformColor;
    std::map<QString, QString> faceMaps;
    int numberFaces;
    float faceConfidence;
    __uint8_t algorithmPermissions;
    bool isHigh;
    int maxNum;                                ///< 识别最大数量
    bool useHalf;                              ///< 是否使用半精度推理模式
    float boxConfThreshold;                    ///< 检测框阈值
    float nmsThreshold;                       ///< 非极大值抑制阈值
    float recConfidenceThreshold;             ///< 识别置信度阈值
};

inline bool isVirtualMachine()
{
    QString dmiPath;
    
#ifdef Q_OS_WIN
    dmiPath = "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System";
#else
    dmiPath = "/sys/devices/virtual/dmi/id/";
#endif
    
    QFile file(dmiPath);
    return file.exists();
}
inline QString getDefaultGateway() {
    QProcess process;
    QString gateway;
    // 根据操作系统的不同选择不同的命令
#ifdef Q_OS_WIN
    QString command = "ipconfig";
    QStringList arguments;
    arguments << "/all";
#elif defined(Q_OS_LINUX)
    QString command = "ip";
    QStringList arguments;
    arguments << "route" << "show" << "default";
#elif defined(Q_OS_MAC)
    QString command = "netstat";
    QStringList arguments;
    arguments << "-nr";
#endif
    
    process.start(command, arguments);
    
    // 等待进程结束
    process.waitForFinished();
    
    // 读取并处理输出
    QString output(process.readAllStandardOutput());
    
#ifdef Q_OS_WIN
    // 使用正则表达式来查找默认网关
    QRegExp rx("Default Gateway[ .]*: (.+?)(\r\n|\n)");
    if (rx.indexIn(output) != -1) {
        gateway = rx.cap(1).trimmed();
    }
#elif defined(Q_OS_LINUX) || defined(Q_OS_MAC)
    // 对于Linux和Mac，分行并查找包含default字样的行
    QStringList lines = output.split('\n');
    QRegularExpression rx("^default via (\\S+)");
    foreach (const QString &line, lines) {
        QRegularExpressionMatch match = rx.match(line);
        if (match.hasMatch()) {
            gateway = match.captured(1);
            break;
        }
    }
    
#endif
    return gateway;
}

inline bool pingAddress(const QString &address) {
    QProcess process;
    QString program = "ping";
    QStringList arguments;

    #ifdef Q_OS_WIN
    arguments << "-n" << "1" << address;
    #else
    arguments << "-c" << "1" << address;
    #endif

    process.start(program, arguments);
    if (!process.waitForStarted()) {
        return false;
    }

    // 使用较长的超时值，确保进程有足够时间完成
    if (!process.waitForFinished(3000)) {
        process.kill(); // 如果超时，强制终止进程
        return false;
    }

    QString output(process.readAllStandardOutput());

    // 简单的 Ping 成功检查逻辑
    #ifdef Q_OS_WIN
    return output.contains("TTL=");
    #else
    return output.contains("1 packets transmitted, 1 received");
    #endif
}

inline int GetCpuIdByAsm_arm(char* cpu_id)
{
    FILE *fp = fopen("/proc/cpuinfo", "r");
    if(nullptr == fp)
    {
        qInfo()<<"failed to open cpuinfo";
        return -1;
    }
    
    char cpuSerial[100] = {0};
    
    while(!feof(fp))
    {
        memset(cpuSerial, 0, sizeof(cpuSerial));
        fgets(cpuSerial, sizeof(cpuSerial) - 1, fp); // leave out \n
        
        char* pch = strstr(cpuSerial,"Serial");
        if (pch)
        {
            char* pch2 = strchr(cpuSerial, ':');
            if (pch2)
            {
                memmove(cpu_id, pch2 + 2, strlen(cpuSerial));
                
                break;
            }
            else
            {
                fclose(fp);
                return -1;
            }
        }
    }
    fclose(fp);
    
    return 0;
}

inline QString getCpuSerialNumber() {
    QFile file("/proc/cpuinfo");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qInfo() << "无法打开 /proc/cpuinfo 文件";
        return QString();
    }
    QTextStream in(&file);
    QString line;
    while (!in.atEnd()) {
        line = in.readLine();
        if (line.startsWith("Serial")) {
            QStringList parts = line.split(":");
            if (parts.size() > 1) {
                QString serial = parts.at(1).trimmed();
                return serial;
            }
        }
    }
    return QString();
}
}


#endif // VIDESDATA_H
