#include "application.h"
#include <fstream>
#include "common/sys_util.h"
#include "mqtt/mqtt_svr.h"

namespace zsy
{
    HANDLE Application::STOP_EVENT = CreateEvent(nullptr, TRUE, FALSE, nullptr);

    // std::shared_ptr<ThreadPool> Application::threadPool = nullptr;
    std::shared_ptr<EventManager> Application::eventManager = nullptr;
    std::shared_ptr<HttpSvr> Application::httpSvr = nullptr;
    std::shared_ptr<MqttSvr> Application::mqttSvr = nullptr;
    std::shared_ptr<MqttCliHolder> Application::mqttCliHolder = nullptr;
    std::shared_ptr<OSS> Application::oss = nullptr;

    std::shared_ptr<ReportSvr> Application::reportSvr = nullptr;

    std::shared_ptr<DeviceHolder> Application::deviceHolder = nullptr;

    std::shared_ptr<Test> Application::test = nullptr;

    void Application::loadConfig()
    {
        LOGGER_INFO("正在加载配置文件：{}", configFile);
        std::ifstream conf_file(configFile);
        if (!conf_file.is_open())
        {
            auto [_,code,msg] = SysUtil::getError();
            LOGGER_ERROR("配置文件加载失败，错误码：{}，错误信息：{}", code, msg);
            exit(1);
        }
        try
        {
            conf_file >> config;
            LOGGER_INFO("配置文件加载完成");
        } catch (const std::exception &e)
        {
            LOGGER_ERROR("配置文件加载失败，请检查配置文件是否有误，{}", e.what());
            exit(1);
        } catch (...)
        {
            LOGGER_ERROR("未知异常，配置文件加载失败");
            exit(1);
        }
    }

    void Application::removePid()
    {
        std::regex pattern(R"(deviceAccessLayer_\d+\.txt)");

        std::filesystem::path path = std::filesystem::path(pidFilePath);

        try
        {
            for (const auto &entry: std::filesystem::directory_iterator(path))
            {
                std::string filename = entry.path().filename().string();
                if (std::regex_match(filename, pattern))
                {
                    std::filesystem::remove(entry.path());
                    LOGGER_INFO("PID 文件删除成功：{}", entry.path().string());
                }
            }
        } catch (const std::exception &e)
        {
            LOGGER_ERROR("PID 文件删除失败：{}", e.what());
        } catch (...)
        {
            LOGGER_ERROR("未知异常，PID 文件删除失败");
        }
    }

    void Application::writePid()
    {
        removePid();
        try
        {
            pid = std::to_string(GetCurrentProcessId());

            auto pidFile = pidFilePath + "\\deviceAccessLayer_" + pid + ".txt";
            std::ofstream outFile(pidFile);
            if (!outFile.is_open())
            {
                LOGGER_ERROR("无法打开文件：{}", pidFile);
            }
            outFile << pid;
            outFile.close();
        } catch (const std::exception &e)
        {
            pid = {};
            LOGGER_ERROR("PID 写入失败：{}", e.what());
        } catch (...)
        {
            pid = {};
            LOGGER_ERROR("未知异常，PID 写入失败");
        }
    }

    Application::Application(const std::string &configFile)
        : configFile(SysUtil::WORK_DIR + "\\config\\" + configFile),
          pidFilePath(SysUtil::WORK_DIR + "\\logs")
    {
        loadConfig();
        auto appProperties = config.get<AppProperties>();
        if (appProperties.daemon)
        {
            FreeConsole();
        }
        if (appProperties.delay > 0)
        {
            LOGGER_INFO("等待...");
            std::this_thread::sleep_for(std::chrono::milliseconds(appProperties.delay * 1000));
        }
        // threadPool = std::make_shared<ThreadPool>("通用线程池");

        eventManager = std::make_shared<EventManager>();

        httpSvr = std::make_unique<HttpSvr>(config);

        oss = std::make_shared<OSS>(config);

        if (appProperties.embedMqtt)
        {
            mqttSvr = std::make_shared<MqttSvr>();
        }

        mqttCliHolder = std::make_shared<MqttCliHolder>(config, eventManager);

        reportSvr = std::make_shared<ReportSvr>(config);

        deviceHolder = std::make_shared<DeviceHolder>(config);

        test = std::make_shared<Test>();
    }

    void Application::run()
    {
        run("config.json");
    }

    void Application::run(const std::string &configFile)
    {
        SetConsoleOutputCP(CP_UTF8);
        LOGGER_INFO("启动中...");
        Application app(configFile);
        app.writePid();
        LOGGER_INFO("启动完成，PID：{}", app.pid);

        while (WaitForSingleObject(STOP_EVENT, INFINITE) != WAIT_OBJECT_0)
        {
        }
    }

    void Application::stop()
    {
        LOGGER_INFO("正在停止服务...");
        SetEvent(STOP_EVENT);
    }

    Application::~Application()
    {
        CloseHandle(STOP_EVENT);
        if (pid.empty()) return;
        auto pidFile = pidFilePath + "\\deviceAccessLayer_" + pid + ".txt";
        auto pathPtr = SysUtil::ch_vlt(pidFile.c_str());
        if (std::remove(pathPtr.get()) != 0)
        {
            auto [_,code,msg] = SysUtil::getError();
            LOGGER_ERROR("PID 文件删除失败：{}，错误码：{}，错误信息：{}", pidFile, code, msg);
        } else
        {
            LOGGER_ERROR("PID 文件删除成功：{}", pidFile);
        }
    }
} // zsy
