#include <iostream>
#include <fstream>
#include <sstream>
#include <csignal>


#include "3th-part/json.hpp"
#include "mqtt/mqtt_client.hpp"
#include "barrier_gate.hpp"

void logExit() {
    std::ofstream logfile("exit_log.txt", std::ios::app);
    if (logfile.is_open()) {
        logfile << "Program exited normally." << std::endl;
        logfile.close();
    } else {
        std::cerr << "Failed to open log file!" << std::endl;
    }
}

void signalHandler(int signal) {
    std::ofstream logfile("exit_log.txt", std::ios::app);
    if (logfile.is_open()) {
        logfile << "Program exited due to signal: " << signal << std::endl;
        logfile.close();
    } else {
        std::cerr << "Failed to open log file!" << std::endl;
    }
    std::exit(signal);  // 确保程序退出
}


int main(int argc, char *argv[])
{
       // 注册正常退出日志函数
    std::atexit(logExit);

    // 注册信号处理函数
    std::signal(SIGINT, signalHandler);   // Ctrl+C
    std::signal(SIGTERM, signalHandler);  // kill 命令
    std::signal(SIGSEGV, signalHandler);  // 段错误
    if (argc < 2)
    {
        std::cout << "please input config file, such as config.json" << std::endl;
        return 0;
    }

    if(access(argv[1], F_OK) != 0)
    {
        std::cerr << "file not exist: " << argv[1] << std::endl;
        return 0;
    }
    std::ifstream file(argv[1]);
    if (!file)
    {
        std::cerr << "can't open file " << argv[1] << std::endl;
        return 0;
    }

    std::string command = "red"; // off/on/
    if(argc == 3)
    {
        command = argv[2];
        std::cout << "command: file" << command << std::endl;
    }

    std::ostringstream ss;
    ss << file.rdbuf();
    std::string content = ss.str();

    if (content.empty())
    {
        std::cout << "config file is empty!" << std::endl;
    }
    else
    {
        try
        {
            nlohmann::json j = nlohmann::json::parse(content);

            std::string ip = j["mqtt_server_ip"];
            uint16_t port = j["mqtt_server_port"];
            std::string user = j["mqtt_server_user"];
            std::string pwd = j["mqtt_server_pwd"];
            auto num_config = j["barrier_num_map"];

            std::map<int, std::string> numbarrier_config;
            for (auto tmp : num_config)
            {
                std::stringstream ss;
                // 将整数转换为字符串
                ss << tmp["id"];
                std::string str_num = ss.str();                    
                numbarrier_config.insert({tmp["id"], str_num});
            }

            mqtt_dataio::client::ins().init(ip, port, user, pwd);

            auto node = std::make_shared<BarrierGateControl>(j,numbarrier_config,command);

            node->exec();
        }
        catch (const std::exception &e)
        {
            std::cerr << "catch exception: " << e.what() << '\n';
            return -1;
        }
    }

    return 0;
}
