#include "platform_init.hpp"
#include <zlog.h>
#include <fstream>
#include <json/json.h>
#include "common/global.hpp"
#include "dbaccess/sql_db.hpp"

extern zlog_category_t *zct;
extern zlog_category_t *zbt;

int GlobalConfig::RUN_MODE = 0;
int GlobalConfig::QuitFlag_G = 1;
int GlobalConfig::LinkStatus_G = 0;
int GlobalConfig::LinkCount = 0;
int GlobalConfig::net0Status = 1;

std::string GlobalConfig::Version = "5.8";
std::string GlobalConfig::MacAddr_G = "";
std::string GlobalConfig::MacAddr_G2 = "";
std::string GlobalConfig::IpAddr_G = "";
std::string GlobalConfig::ServerIP = "";
std::string GlobalConfig::NetStatus = "";
std::string GlobalConfig::NetType = "";
std::string GlobalConfig::NR5GTemp = "";
int GlobalConfig::serverStatus = 0;
int GlobalConfig::NetSignal = 0;
int GlobalConfig::ServerPort = 0;
int GlobalConfig::threadStatus = 1;
int GlobalConfig::day = 0;

extern std::map<std::string, compressWaveChannel> g_mapCompress;
extern std::map<std::string, WaveChannel> g_mapWaveChannel;

TopicList GlobalConfig::Topic_G;
ZigbeeInfo GlobalConfig::ZigbeeInfo_G;
ZIGBEE GlobalConfig::Zigbee_G;
GPIOInfo GlobalConfig::GPIO_G;
std::string GlobalConfig::DbName_G = "/opt/configenv/cidn.db"; //数据库名称
std::string GlobalConfig::Config_G = "/opt/configenv/config.ini";
std::string GlobalConfig::UartName_G = "/dev/ttymxc4";

// 处理ZigBee网络接收过程的PanID切换
enumZigBeeTransmitStatus GlobalConfig::EnterZigBeeWaveTransmittingFlag_G = NO_ENTER_TRANSMITTING_STATUS;
int GlobalConfig::EnterZigBeeWaveTransmittingCnt_G = 0;

PlatformInit::PlatformInit() {}

PlatformInit::~PlatformInit() {}

void PlatformInit::Init() {
    try {
        GlobalConfig::MacAddr_G = GetLocalMac("eth0");
        GlobalConfig::MacAddr_G2 = GetLocalMac("eth1");
        transform(GlobalConfig::MacAddr_G.begin(), GlobalConfig::MacAddr_G.end(), GlobalConfig::MacAddr_G.begin(), ::toupper);
        transform(GlobalConfig::MacAddr_G2.begin(), GlobalConfig::MacAddr_G2.end(), GlobalConfig::MacAddr_G2.begin(), ::toupper);
        GlobalConfig::IpAddr_G = IpAddrInit();
        zlog_info(zbt, "GlobalConfig::IpAddr_G : %s", GlobalConfig::IpAddr_G.c_str());
        ConfigFileCheck();
        zlog_info(zbt, "ConfigFileCheck");
        TopicInit();
        zlog_info(zbt, "TopicInit");
        ServerIpInit();
        zlog_info(zbt, "TopicInit");
        Sqlite3Init();
        GPIOInit();

        zlog_info(zbt, "ServerIP : %s ", GlobalConfig::ServerIP.c_str());
        std::string strMac = sqlite_db_ctrl::instance().GetData("t_gateway_info", "gatewayMAC", NULL);
        if (strMac == "60294D208517") {
            char szUpdateSql[100] = {0x00};
            sprintf(szUpdateSql, "gatewayMAC = '%s'", GlobalConfig::MacAddr_G.c_str());
            sqlite_db_ctrl::instance().UpdateTableData("t_gateway_info", szUpdateSql, NULL);
        } else if (strMac != GlobalConfig::MacAddr_G) {
            zlog_error(zbt, "MAC error strMac1 = %s,MacAddr_G1 = %s", strMac.c_str(), GlobalConfig::MacAddr_G.c_str());
            strMac.insert(2, ":");
            strMac.insert(5, ":");
            strMac.insert(8, ":");
            strMac.insert(11, ":");
            strMac.insert(14, ":");
            ModifyMac((char*)strMac.c_str());
        }

    } catch (...) {
        zlog_error(zbt, "PlatFormInit exception happend.");
        std::string errorinfo = "系统初始化异常";
    }
    char whereCon[128] = {0};
    char insertSql[128] = {0};
    int rows = 0;
    std::string MeasurementID = "0";
    std::string ShortAdd = "0";
    array_t arrResult = sqlite_db_ctrl::instance().GetDataMultiLineTransaction(T_SENSOR_INFO(TNAME), " MeasurementID,zigbeeShortAddr ", NULL);
    if (arrResult.size() > 1)
    {
        for (size_t i = 0; i < arrResult.size(); i++) {
            compressWaveChannel tempchannel;
            WaveChannel tempwavechannel;
            g_mapCompress.insert(std::make_pair(arrResult[i][1], tempchannel));
            g_mapWaveChannel.insert(std::make_pair(arrResult[i][0], tempwavechannel));
            MeasurementID = arrResult[i][0];
            ShortAdd = arrResult[i][1];
            sprintf(whereCon, "MeasurementID = '%s' ", arrResult[i][0].c_str());
            rows = sqlite_db_ctrl::instance().GetTableRows("t_shutdown_info",whereCon);
            zlog_info(zbt, "MeasurementID = %s,ShortAdd = %s,rows = %d", MeasurementID.c_str(), ShortAdd.c_str(), rows);
            if(rows < 1){   
                memset(insertSql,0,sizeof(insertSql));
                sprintf(insertSql, " '%s','%s','0','0','0','0'",
                    MeasurementID.c_str(), ShortAdd.c_str());
                sqlite_db_ctrl::instance().InsertData("t_shutdown_info", insertSql);  
            }
            rows = sqlite_db_ctrl::instance().GetTableRows("t_debug_info",whereCon);
            if(rows < 1){
                memset(insertSql,0,sizeof(insertSql));
                sprintf(insertSql, " '%s','%s','','','','','','0',''",
                            MeasurementID.c_str(), ShortAdd.c_str());           
                sqlite_db_ctrl::instance().InsertData("t_debug_info", insertSql);
            }
            rows = sqlite_db_ctrl::instance().GetTableRows("t_wave_triger_info",whereCon);
            if(rows < 1){
                memset(insertSql,0,sizeof(insertSql));
                sprintf(insertSql, " '%s','%s','0','0','0','0','0'",
                    MeasurementID.c_str(), ShortAdd.c_str());
                sqlite_db_ctrl::instance().InsertData("t_wave_triger_info", insertSql);
            }
        }
    }
}

void PlatformInit::TopicInit() {
    GlobalConfig::Topic_G.mPubData = "wireless/statisticData/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mPubStatus = "wireless/status/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mPubHeart = "wireless/heart/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mPubConfig = "wireless/configureInfo/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mPubWaveData = "wireless/realTimeData/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mPubWaveSecondData = "wireless/secondTimeData/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mPubCmd = "wireless/cmd/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mSubData = "cmd/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mPubRep = "wireless/resp/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mPubTiming = "equipment/cmd/" + GlobalConfig::MacAddr_G;
    GlobalConfig::Topic_G.mPubLocalWifi = "up/" + GlobalConfig::MacAddr_G + "/recive/wifi";
    GlobalConfig::Topic_G.mPubLocalWaveServer = "up/" + GlobalConfig::MacAddr_G + "/recive/waveserver";
    GlobalConfig::Topic_G.mPubLocalWaveQt = "up/" + GlobalConfig::MacAddr_G + "/recive/waveqt";
    GlobalConfig::Topic_G.mPubLocalConfig = "up/" + GlobalConfig::MacAddr_G + "/recive/config";
    GlobalConfig::Topic_G.mPubLocalTrigger = "up/" + GlobalConfig::MacAddr_G + "/recive/trigger";
    GlobalConfig::Topic_G.mPubLocalCmd = "up/" + GlobalConfig::MacAddr_G + "/recive/cmd";
}

void PlatformInit::ConfigFileCheck() {
    if (access(SYSTEMINFOFILE, 0) < 0) {
        WriteStr2Config(SYSTEMINFOFILE, "SystemInfo", "dataNodeGatewayName", "");
        WriteStr2Config(SYSTEMINFOFILE, "SystemInfo", "dataNodeGatewayAssetId", "");
        WriteStr2Config(SYSTEMINFOFILE, "SystemInfo", "dataNodeGatewayAddedBy", "");
        WriteStr2Config(SYSTEMINFOFILE, "SystemInfo", "dataNodeGatewayAddedDate", "");
        WriteStr2Config(SYSTEMINFOFILE, "SystemInfo", "timezone", "UTC+8");
        WriteStr2Config(SYSTEMINFOFILE, "SystemInfo", "dataNodeGatewayNo", GlobalConfig::MacAddr_G);
        WriteStr2Config(SYSTEMINFOFILE, "Area", "countryId", "");
        WriteStr2Config(SYSTEMINFOFILE, "Area", "provincesId", "");
        WriteStr2Config(SYSTEMINFOFILE, "Area", "cityListId", "");
        WriteStr2Config(SYSTEMINFOFILE, "Uint", "uint", "ST");
    }

    if (access(NETWORKCONFIG, 0) < 0) {
        WriteStr2Config(NETWORKCONFIG, "Net", "dnsName", " ");
        WriteStr2Config(NETWORKCONFIG, "Net", "networkPortStatus", "DHCP");
        WriteStr2Config(NETWORKCONFIG, "Net", "gateway", "0.0.0.0");
        WriteStr2Config(NETWORKCONFIG, "Net", "subnetMask", "0.0.0.0");
        WriteStr2Config(NETWORKCONFIG, "Net", "ipAddress", "0.0.0.0");
        WriteStr2Config(NETWORKCONFIG, "Net", "hostName", "0.0.0.0");
    }

    if (access(SERVERCONFIG, 0) < 0) {
        WriteStr2Config(SERVERCONFIG, "Server", "localServerIpAddress", "0.0.0.0");
        WriteStr2Config(SERVERCONFIG, "Server", "localServerPort", "51613");
    }
}

int PlatformInit::ServerIpInit() {
    if (access(SERVERCONFIG, 0) >= 0) {
        GlobalConfig::ServerIP = ReadStrByOpt(SERVERCONFIG, "Server", "localServerIpAddress");
        GlobalConfig::ServerPort = atoi(ReadStrByOpt(SERVERCONFIG, "Server", "localServerPort").c_str());
    }
    return 0;
}

void PlatformInit::Sqlite3Init() {
    sqlite_db_ctrl::instance().OpenDB(GlobalConfig::DbName_G.c_str());
    int nType = readIntValue("Update", "type", (char*)GlobalConfig::Config_G.c_str());
    if (nType == 1) {
        sqlite_db_ctrl::instance().SqliteInitDel(GlobalConfig::DbName_G.c_str());
        writeIntValue("Update", "type", 0, (char*)GlobalConfig::Config_G.c_str());
    }
    sqlite_db_ctrl::instance().SqliteInit(GlobalConfig::DbName_G.c_str());
    zlog_info(zbt, "Sqlite3Init ");
}

void PlatformInit::GPIOInit() {
    GlobalConfig::GPIO_G.zigAckrep = 119;
    GlobalConfig::GPIO_G.zigAckreset = 120;
    GlobalConfig::GPIO_G.zigReset = 116;
    GlobalConfig::GPIO_G.wifiReset = 8;
    GlobalConfig::GPIO_G.commRest = 8;
    GlobalConfig::GPIO_G.power = 9;
    GlobalConfig::GPIO_G.errorLed = 130;
}

void PlatformInit::SystemInfoInit() {
    std::ifstream ifileOut(SYSTEMINFOFILE);
    Json::Reader recvReader;
    Json::Value Systeminfo;
    //从配置文件中读取json数据
    if (ifileOut.is_open()) {
        zlog_info(zbt, "open %s", SYSTEMINFOFILE);
    } else {
        zlog_error(zbt, "fail to open:%s", SYSTEMINFOFILE);
        return;
    }
    if (!recvReader.parse(ifileOut, Systeminfo, false)) {        
        ifileOut.close();
        zlog_error(zbt, "fail to parse:%s", SYSTEMINFOFILE);
        return;
    }
    ifileOut.close();

    Systeminfo["dataWatchIpAddress"] = GlobalConfig::IpAddr_G;
    Systeminfo["softVersion"] = GlobalConfig::Version;

    Json::StyledWriter sw;
    std::ofstream os;
    os.open(SYSTEMINFOFILE);
    os << sw.write(Systeminfo);
    os.close();
}

int  PlatformInit::UserInit() {
    std::string userName = ReadStrByOpt(SYSTEMINFOFILE, "UserInfo", "UserName");
    int ret = 0;
    if (userName.length() == 0) {
        ret = WriteStr2Config(SYSTEMINFOFILE, "UserInfo", "UserName", "Admin");
        if (ret != 0) {
            return 1;
        }

        ret = WriteStr2Config(SYSTEMINFOFILE, "UserInfo", "adminPassword", "njchaos");
        if (ret != 0) {
            return 2;
        }

        ret = WriteStr2Config(SYSTEMINFOFILE, "UserInfo", "userPassword", "");
        if (ret != 0) {
            return 3;
        }
    }
    return ret;
}

void PlatformInit::EquipIpInit(std::string eth) {
    // eth0 初始化
    std::string networkPortStatus = ReadStrByOpt(NETWORKCONFIG, eth, "networkPortStatus");
    std::string subnetMask = ReadStrByOpt(NETWORKCONFIG, eth, "subnetMask");
    std::string gateway = ReadStrByOpt(NETWORKCONFIG, eth, "gateway");
    std::string dataWatchIpAddress = ReadStrByOpt(NETWORKCONFIG, eth, "ipAddress");
    std::string strStatus = GetFileContent(NETWORK, 18);
    zlog_info(zbt, "strStatus:%s\n networkPortStatus:%s dataWatchIpAddress:%s subnetMask:%s gateway:%s\n", strStatus.c_str(), networkPortStatus.c_str(), dataWatchIpAddress.c_str(), subnetMask.c_str(), gateway.c_str());

    if (0 == networkPortStatus.compare("DHCP")) {
        zlog_info(zbt, "dhcp config\n");
        std::string cmd = "";
        system("sed -i '17c auto eth0' /etc/network/interfaces");
        system("sed -i '18c iface eth0 inet dhcp' /etc/network/interfaces");
        system("sed -i '20c                     ' /etc/network/interfaces");
        system("sed -i '21c                     ' /etc/network/interfaces");
        system("sed -i '22c                     ' /etc/network/interfaces");

//        flag = 0;
    }
    if (0 == networkPortStatus.compare("STATIC")) {
        std::string cmd = "";
        system("sed -i '18c iface eth0 inet static' /etc/network/interfaces");
        if (dataWatchIpAddress.length() > 0) {
            cmd = "sed -i '20c address " + dataWatchIpAddress + "' /etc/network/interfaces";
        } else {
            cmd = "sed -i '20c address 0.0.0.0' /etc/network/interfaces";
        }
        system(cmd.c_str());
        cmd.clear();

        if (subnetMask.length() > 0) {
            cmd = "sed -i '21c netmask " + subnetMask + "' /etc/network/interfaces";
        } else {
            cmd = "sed -i '21c netmask 255.255.255.0' /etc/network/interfaces";
        }
        system(cmd.c_str());
        cmd.clear();

        if (gateway.length() > 0) {
            cmd = "sed -i '22c gateway " + gateway + "' /etc/network/interfaces";
        } else {
            cmd = "sed -i '22c gateway 0.0.0.0' /etc/network/interfaces";
        }
        system(cmd.c_str());
        cmd.clear();
    }
    zlog_info(zbt, "system reboot by reboot system call");
    system("sync");
    sleep(1);
    system("reboot");
}
