#include "thread_func.hpp"

#include <time.h>
#include <math.h>
#include <string.h>
#include <cstdlib>
#include <linux/types.h>
#include <sys/sysinfo.h>
#include <dirent.h>
#include <map>
#include <zlog.h>
#include "mqttclient/mqtt_client.h"
#include "uart/uart.hpp"
#include "common/common_func.hpp"
#include "jsonparse/communication_cmd.hpp"
#include "wifi_5g/wpa_client.h"

extern zlog_category_t *zct;
extern zlog_category_t *zbt;

void CheckThread() {
    zlog_info(zbt, "ENTER CHECK THREAD ");

    int heart_count = 0;

    int time_check = 0;
    int reset_flag = 0;
    int online_check = 0;
    int HardStatus = 0;
    int logClean = 0;
    int Battery = 0;
    int commSignal = 0;
    int loose_check = 0;
    int mqttresend = 0;

    while (GlobalConfig::QuitFlag_G) {
        GlobalConfig::threadStatus = 1;
        sleep(1);
        if (10 == heart_count) {
            if (GlobalConfig::LinkCount > 30) {
                zlog_error(zct, "MQTT connect failed ");
                char connect[10] = {0x00};
                readStringValue("config", "connect", connect, (char *)GlobalConfig::Config_G.c_str());
                if (atoi(connect)) {
                    zlog_error(zct, "MQTT connect failed,reboot");
                    exit(0);
                }
            }
            std::string ipTemp = IpAddrInit();
            GlobalConfig::IpAddr_G = ipTemp;            
            heart_count = 0;
        }
         if (7200 == time_check) { // 2h 
            time_check = 0;
            char buf[256] = {0};
            char buf2[256] = {0};
            sprintf(buf, "{\"dataNodeGatewayNo\":\"%s\",\"cmd\":\"12\",\"status\":\"REQ\"}", GlobalConfig::MacAddr_G.c_str());
            sprintf(buf2, "{\"dataWatchNo\":\"%s\",\"cmd\":\"12\",\"status\":\"REQ\"}", GlobalConfig::MacAddr_G.c_str());
            std::string str = std::string(buf);
            std::string str2 = std::string(buf2);
            
            int iRet = data_publish(str.c_str(), GlobalConfig::Topic_G.mPubTiming.c_str());
            iRet = data_publish(str.c_str(), GlobalConfig::Topic_G.mPubCmd.c_str());
            iRet = data_publish(str2.c_str(), GlobalConfig::Topic_G.mPubTiming.c_str());
            iRet = data_publish(str2.c_str(), GlobalConfig::Topic_G.mPubCmd.c_str());
            if (iRet != 0) {
                zlog_error(zct, "MQTT connect failed ,time check");
                char connect[10] = {0x00};
                readStringValue("config", "connect", connect, (char *)GlobalConfig::Config_G.c_str());
                if (atoi(connect)) {
                    zlog_error(zct, "MQTT connect failed,time check ,reboot");
                    exit(0);
                }
#ifdef NR5G_MODULE
                dial.closePort();
                gpio_set(GlobalConfig::GPIO_G.commRest, 0);
                zlog_warn(zct, "GPIO 8 start");
                sleep(2);
                gpio_set(GlobalConfig::GPIO_G.commRest, 1);
                zlog_warn(zct, "GPIO 8 End");
                sleep(20);
                dial.openPort("/dev/ttyUSB2");
                dial.setState();
#endif
#ifdef WIFI_MODULE
                zlog_warn(zct, "WiFi reset!");
                gpio_set(GlobalConfig::GPIO_G.wifiReset, 0);
                sleep(5);
                gpio_set(GlobalConfig::GPIO_G.wifiReset, 1);
                sleep(5);
                wifi::WPAClient wpa;
                wpa.ReconnectWiFi();
                system("/etc/init.d/wpa_restart");
                system("udhcpc -i wlan2 &");
#endif
            }
         }
        if (HardStatus == 3600) { // one hour 3600
            JsonData jd;
            jd.JsonCmd_07();
            HardStatus = 0;
            sqlite_db_ctrl::instance().SaveSystemHardStatus();
            int hour = 0;
			struct tm *tm_info = get_current_date();
			hour = tm_info->tm_hour;
            int statistics = readIntValue( "config", "statistics",(char*)GlobalConfig::Config_G.c_str());
			if(statistics == 0 && hour > 13 ){
				writeIntValue("config", "statistics",1,(char*)GlobalConfig::Config_G.c_str());
			}else if(statistics == 1 && hour < 13){
				writeIntValue("config", "statistics",0,(char*)GlobalConfig::Config_G.c_str());
			}
            sqlite_db_ctrl::instance().ShutdownCheck();
        }
        }
        if (mqttresend == 7200) {
            mqttresend = 0;
            zlog_info(zct, "mqttresend check");
            Json::Value jsHeart;
            Json::FastWriter fw;
            jsHeart["dataNodeGatewayNo"] = GlobalConfig::MacAddr_G;
            jsHeart["status"] = "online_V" + GlobalConfig::Version;
            jsHeart["IP"] = GlobalConfig::IpAddr_G;
            std::string strJson = fw.write(jsHeart);
            int iRet = data_publish(strJson.c_str(), GlobalConfig::Topic_G.mPubHeart.c_str());
            if (iRet == 0) {
                sqlite_db_ctrl::instance().QueryofflineData();
            }
        }

        if (1800 == online_check) {
            online_check = 0;
            JsonData jd;
            int Count = sqlite_db_ctrl::instance().GetTableRows(T_SENSOR_INFO(TNAME), NULL);
            if (Count > 0) {
                jd.DataNodeStatusCheck();
                char localtimestamp[32] = {0};
                GetTimeNet(localtimestamp, 1);
                std::string nowTimetamp = std::string(localtimestamp);
                char selectCon[128] = {0};
                sprintf(selectCon, " sendMsg <> '' ORDER BY timeStamp DESC  LIMIT 0,1");
                sleep(1);
                std::string strTime = sqlite_db_ctrl::instance().GetData(T_DATASTATIC_INFO(TNAME), "timeStamp", selectCon);
                long lTime = atol(nowTimetamp.c_str()) - atol(strTime.c_str());
                zlog_info(zct, "online check = %ld", lTime);
            }
           
        }
        if (7200 == Battery) {
            Battery = 0;
            zlog_info(zct, "Battery");
            sqlite_db_ctrl::instance().CalculateBattery();
            JsonData jd;
            jd.JsonCmd_07();
            jd.JsonCmd_29();
            jd.JsonCmd_30();
            jd.JsonCmd_31();
        }

        if (3500 == loose_check) {
            zlog_info(zct, "loosecheck\n");
            loose_check = 0;
            int looseEnable = readIntValue("config", "looseEnable", (char *)GlobalConfig::Config_G.c_str());
            if (looseEnable == 1)
            {
                zlog_warn(zct, "loosecheck\n");
                sqlite_db_ctrl::instance().CalculateDip();
            }
            
        }

        if (18000 == commSignal) { // 5h
            Json::Value jsBody, jsonVal;
            Json::FastWriter showValue;
            if (GlobalConfig::NetStatus == "\"NOCONN\"" || GlobalConfig::NetStatus == "\"CONNECT\"") {
                if (GlobalConfig::NetSignal == 0) {
                    jsBody["communicationSignal"] = "未知";
                } else if (GlobalConfig::NetSignal > -80) {
                    jsBody["commSignal"] = "优";
                } else if (GlobalConfig::NetSignal > -90 && GlobalConfig::NetSignal < -80) {
                    jsBody["commSignal"] = "良";
                } else if (GlobalConfig::NetSignal > -105 && GlobalConfig::NetSignal < -90) {
                    jsBody["commSignal"] = "一般";
                } else if (GlobalConfig::NetSignal < -105) {
                    jsBody["commSignal"] = "弱";
                } else if (GlobalConfig::NetSignal < -115) {
                    jsBody["commSignal"] = "不稳定";
                }

            } else if (GlobalConfig::NetStatus == "\"SEARCH\"") {
                jsBody["commSignal"] = "搜索网络";
            } else if (GlobalConfig::NetStatus == "\"LIMSRV\"") {
                jsBody["commSignal"] = "未插卡";
            } else {
                jsBody["commSignal"] = "未知";
            }

            jsonVal["cmd"] = "53";
            std::string dataBody = showValue.write(jsBody);
            jsonVal["cmdBody"] = dataBody;
            data_publish(showValue.write(jsonVal).c_str(), GlobalConfig::Topic_G.mPubConfig.c_str());
        }
        if (21600 == logClean) {
            logClean = 0;            
            char localtimestamp[32] = {0};
            GetTimeNet(localtimestamp, 1);
            char whereCon[1024] = {0};
            sprintf(whereCon, " timestamp < '%ld' ", atol(localtimestamp) - 2592000); //删除1个月前的数据
            sqlite_db_ctrl::instance().DeleteTableData(" t_battery_history ", whereCon);
            sqlite_db_ctrl::instance().DeleteTableData(" receive_wave_status ", whereCon);
            sqlite_db_ctrl::instance().ClearExpireData();
        }
#ifdef WIFI_MODULE
        if (wifi_reconnect_count == 600) { // 每 10分钟，重连WiFi网络
            wifi_reconnect_count = 0;
            wifi::WPAClient wpa;
            std::string netssid = wpa.GetNetSsid();
            std::string currentssid = "";
            if (0 == netssid.compare("")) {
                netssid = wpa.GetNetSsid();
            }

            if (netssid.length() > 0) {
                currentssid = wpa.GetCurrentSSID();
                if (currentssid.length() > 0) {
                    char buf[64] = {0};
                    std::string rssiSend = "";
                    rssiSend = "/opt/Cidn/wpa_cli signal_poll|grep RSSI | cut -f 2 -d '='";
                    system_custom(rssiSend.c_str(), buf);
                    std::string Rssi = std::string(buf);

                    memset(buf, 0, 64);
                    sprintf(buf, "wifi:true Rssi:%s", Rssi.c_str());
                    zlog_info(zct, "%s\n", buf);

                } else {
                    std::string runinfo = "wifi:false\n";
                    zlog_info(zct, "%s\n", runinfo.c_str());
                }
            }
            if (wpa.ReconnectWiFi()) {
                zlog_info(zct, "wifi reconnect ok\n");
            }
        }
#endif

        if (reset_flag > 7200) {
            reset_flag = 0;
        }
        Battery++;
        reset_flag++;
        time_check++;
        heart_count++;
        online_check++;
        HardStatus++;
        logClean++;
        loose_check++;
        mqttresend++;
#ifdef WIFI_MODULE
        wifi_reconnect_count++;
#endif

}
