#include "Application.h"

#include "common/Utils.h"
#include "Config.h"
#include "app/Device.h"
#include "database/DaoEntity.h"
#include "database/Dao.h"
#include "app/Station.h"
#include "app/Device.h"
#include "protocol/HttpEntity.h"
#include "common/Spdlogger.h"
#include "protocol/MqttEntity.h"
#include "DataStruct.h"

void Application::init()
{
    // 初始化系统配置，读取配置文件
    Config::init("assets/config/app.json");
    if (Config::option.debug)
    {
        spdlog::set_level(spdlog::level::debug); // 设置全局日志等级为 debug
        spdlog::debug("[app] spdlog debug enable.");
    }

    // MQTT 数据结构
    REGAddr::load("assets/config/regaddrs.json");
    // 设备读取寄存器的地址定义
    REGAddr::loadParamAddr("assets/config/regaddrsShow.json");

    // 设置数据库配置
    DaoEntity::setOption(Config::option.database.host,
        Config::option.database.port,
        Config::option.database.user,
        Config::option.database.passwd,
        Config::option.database.dbname);
    spdlog::info("[app] set database option: host={}, port={}, user={}, dbname={}", 
        Config::option.database.host, 
        Config::option.database.port,
        Config::option.database.user, 
        Config::option.database.dbname);

    // 连接数据库，读取基础信息

    // 初始化系统基础数据
    this->isInit = appdata.init();

    // 创建设备处理线程
    std::thread([=]() { runThreadDevice(); }).detach();

    // 创建HTTP服务线程
    std::thread([=]() {
        while (!isQuit) {
            HttpEntity http;
            http.listen("0.0.0.0", Config::option.http.port); // 阻塞
        }
    }).detach();

    // 统计分析
    std::thread([=]() { runThreadStat(); }).detach();

    // 创建主业务循环线程
    std::thread([=]() { runThreadMain(); }).detach();
}


void Application::runThreadDevice()
{
    while (!isQuit)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

void Application::runThreadMain()
{
    std::this_thread::sleep_for(std::chrono::seconds(10)); // 延迟10秒执行

    while (!isQuit)
    {
        if (!this->isInit) // 初始化失败
        {
            std::this_thread::sleep_for(std::chrono::seconds(10));
            this->isInit = appdata.init();
            if (!this->isInit) { continue; }
        }

        static TimeTick ttMqtt; // 检查 场站的 MQTT 连接
        if (ttMqtt.elapse(10))
        {
            for (auto& item : appdata.mapStation)
            {
                auto& station = item.second;
                // 检查MQTT的连接状态
                if (!Config::option.mqtt.host.empty()) { station->initMqtt(); }
                // 检查设备的在线状态
                station->checkDevice();
            }
        }

        static TimeTick ttMqttPolling; // 召测
        int mqttInterval = Config::option.mqtt.interval;
        if (!Config::option.mqtt.host.empty() && mqttInterval > 0 && ttMqttPolling.elapse(10))
        {
            for (auto& item : appdata.mapStation)
            {
                auto& station = item.second;
                if (Utils::time() - station->getPollingTS() > mqttInterval)
                {
                    item.second->polling();
                }
            }
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

void Application::runThreadStat()
{
    int nCachePos = 0;
    while (!isQuit)
    {
        static TimeTick ttStat(1);
        if(Config::option.stat.enabled && ttStat.elapse(Config::option.stat.interval))
        {
            // 设备历史数据（电压、电流、功率），存储到 history_day
            // 统计数据，存储到 stat_day
            for (auto item: appdata.mapStation)
            {
                item.second->writeStatistic();
            }
        }
        else
        {
            //spdlog::info("保存历史数据倒计时: {}", 600 - offset);
        }

        static TimeTick ttStatPredict;
        if (ttStatPredict.elapse(600))
        {
            for (auto item : appdata.mapStation)
            {
                item.second->predict();
            }
        }

        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}