#ifndef TESTSERVICE_H
#define TESTSERVICE_H

#include <QTimer>
#include <QDateTime>
#include <QtSerialPort/QSerialPort>
#include <QObject>
#include <QSemaphore>
#include <QThread>
#include <QString>
#include <QVector>
#include <QMutex>
#include <QDebug>
//#include"Standard.h"
#include "tank.h"
#include "Deviceinfo.h"
#include "report.h"
#include"Msgbox.h"
#include"serialui.h"
#include <QSignalSpy>

//#define MAX_COMPARTMENT_NUM  (4)
#define AVERAGE_PRESSURE_COUNT (1)   //5个不代表5秒， 要看采样频率

typedef enum _Ret_Value{
    Ret_Excepion = -3,  //特指漏气严重
    Ret_Failed = -2,
    Ret_Timeout = -1,
    Ret_OK = 0,
    Ret_Exit = 1
}Ret_Value;


enum Valve_OP{
    Valve_OP_Open = 0,
    Valve_OP_Close,
};

enum Test_Step{
    Test_Step_Start,
    Test_Step_AddPressure,
    Test_Step_KeepPressure,
    Test_Step_KeepEnd,
    Test_Step_reliefPressure,
    Test_Step_End,
};

enum Test_Stage{
    Test_Stage_SysTest,
    Test_Stage_ValveTest,
    Test_Stage_UNKown,
};

enum Test_Direction{
    Test_Direction_Positive,
    Test_Direction_Negative,
    Test_Direction_Unkown,
};

class TestExpect{
public:
    int volume;
    double target;   //pressure value
    int timeout;       // timeout (s)
};


class TestService: public QThread
{
    Q_OBJECT
    Q_ENUMS(Valve_ID)

public:
    TestService(QThread *parent = nullptr);
    ~TestService();

    enum Valve_ID {
        Valve_ID_INTAKE=0,       //进气阀
        Valve_ID_VACUUM,         //真空阀
        Valve_ID_VENT,           //泄气阀
        Valve_ID_4,
        Valve_ID_All,
    };


    Q_INVOKABLE  void init();
    Q_INVOKABLE  bool setTankinfo(const QVariantList& list);
    Q_INVOKABLE  bool valve_open(Valve_ID id);
    Q_INVOKABLE  bool valve_close(Valve_ID id);
    Q_INVOKABLE QString read_PressureValue();
    Q_INVOKABLE  bool pressure_zero();
    Q_INVOKABLE bool ballvalve_control(QString position_str);
    Q_INVOKABLE QJsonObject ballvalve_status();
    Q_INVOKABLE bool tstart(int compartmentid, int direction);  //direction : 0 positive test , 1 negative test
    Q_INVOKABLE bool tselfstart(int compartmentid, int direction);  //direction : 0 positive test , 1 negative test
    Q_INVOKABLE bool tstop(int compartmentid);
    Q_INVOKABLE bool reportpic_Ready(int compartmentid);
    Q_INVOKABLE bool check_alltest_ok(int with_tips);
    Q_INVOKABLE bool genReport(QString word_path, QString pic_dir);
    Q_INVOKABLE bool genReport_Self(QString word_path, QString pic_dir);
    Q_INVOKABLE bool genReport_Self2(const QString& jsonStr, QString word_path, QString pic_dir);

    Q_INVOKABLE QJsonObject get_vrs_items();
    Q_INVOKABLE QJsonObject get_bls_items();

    Q_INVOKABLE bool set_item_result(const QString& jsonStr );

    Q_INVOKABLE bool set_leakage_value(const QString& jsonStr);
    Q_INVOKABLE QJsonObject get_selftest_info();

signals:
   void sigPressure(int id, QVariantMap  pressure_map);

   void sigState(int id, QString state_str1, QString state_str2);
   void sigSystemResult(int id, QString delta_str, bool bPassed);
   void sigValveResult(int id, QString delta_str, bool bPassed);
   void sigSelfTestResult(int id, QString delta_str, bool bPassed);
   void sigStop(int id);

   void onNotice(QString qstr);
   void onWarning(QString qstr);
   void onGenreportProgress(QString qstr);

   void operate();

public slots:
   void receive_reportprogress(QString qstr);

private:
    //bool Adjust_pressure(unsigned short voltage);

    void push_pressurelist(double pressure);
    void clear_pressurelist();
    double calculate_averagepressure();

    bool OpenSerial3();
    bool OpenSerial4();

    bool self_checking();
    bool test_init();

    void dump_comstatistic();

    // 0   ok
    // -1  timeout
    // -2  error
    Ret_Value  PositivePressure_Add(const TestExpect& expect, bool bSavedata = false);

    // 0   ok
    // -1  timeout
    // -2  error
    Ret_Value  Pressure_Relief(const TestExpect& expect);
    Ret_Value  Pressure_Relief();

    // 0   ok
    // -1  timeout
    // -2  error
    Ret_Value  Pressure_Keep(int keeptime, double& start_value, double& end_value);



    int make_messagebox(Test_Direction direction, Test_Step step, Ret_Value ret_v);


   //QSerialPort * m_SerialPort3;
   //QSerialPort * m_SerialPort4;
   //QMutex        m_Serial3mutex;
   //QMutex        m_Serial4mutex;
   //QSignalSpy    m_spy3
   SerialUi      m_SerialUi3;
   SerialUi      m_SerialUi4;

   QTimer *      m_pTimer_1;  //read pressure value
   QTimer*       m_pTimer_2;  // testing process
   //QThread       m_Thread;
   int           m_compartmentid;
   bool          m_bRunning;
   bool          m_bRealEnd;

   Tanker        m_tank;
   //QString       m_standardname;
   Standard      m_standard;
   Report        m_report;

   QList<float>  m_pressurelist; //用来计算平均压力
   QMutex        m_pressuremutex;

   Test_Stage     m_stage;
   Test_Step      m_step;
   Test_Direction m_direction;

   DeviceInfo     m_devinfo;
   DeviceInfo     m_devinfo2;//系统自测检测 历史记录生成报告用

   MsgBox         m_msgbox;


 protected:
    void run() override;

 public slots:

 private slots:
     void OnTimer1();
     void OnTimer2();

 };

#endif // TESTSERVICE_H
