// main.cpp
#include "app_config.hpp"
#include "rtsp_manager.hpp"
#include "logger.hpp"
#include "mqtt_client_wrapper.hpp"
#include <thread>
#include <atomic>
#include <csignal>
#include <unistd.h>
#include <chrono>

constexpr bool ENABLE_RTSP_THREAD = true;
constexpr bool ENABLE_MQTT_THREAD = true;

std::atomic<bool> g_running(true);

static void minimal_signal_handler(int signum)
{
    g_running.store(false, std::memory_order_relaxed);
    const char msg[] = "[MAIN] Signal received, initiating shutdown...\n";
    write(STDERR_FILENO, msg, sizeof(msg) - 1);
}

int main()
{
    struct sigaction sigAct{};
    sigAct.sa_handler = minimal_signal_handler;
    sigemptyset(&sigAct.sa_mask);
    sigAct.sa_flags = 0;
    sigaction(SIGINT, &sigAct, nullptr);
    sigaction(SIGTERM, &sigAct, nullptr);
    signal(SIGPIPE, SIG_IGN);

    Logger::set_log_to_file(get_executable_dir_file_path("app.log"));

    try
    {
        g_app_config = AppConfig::load_from_file(get_executable_dir_file_path("config.json"));
    }
    catch (const std::exception &e)
    {
        LOG_ERROR(std::string("Failed to load config: ") + e.what());
        return -1;
    }

    std::atomic<bool> rtsp_thread_exited(false);
    std::atomic<bool> mqtt_thread_exited(false);

    // 初始化 GStreamer
    RTSPManager::init();

    std::thread rtsp_thread;
    std::thread mqtt_thread;

    if (ENABLE_RTSP_THREAD)
    {
        rtsp_thread = std::thread([&]()
                                  {
            RTSPManager::start(g_app_config.cameras);
            rtsp_thread_exited.store(true, std::memory_order_relaxed); });

        LOG_INFO("[MAIN] RTSP thread started");
    }
    else
    {
        LOG_INFO("[MAIN] RTSP thread disabled by toggle");
    }

    if (ENABLE_MQTT_THREAD)
    {
        mqtt_thread = std::thread([&]()
                                  {
            mqtt_client_thread_func();
            mqtt_thread_exited.store(true, std::memory_order_relaxed); });

        LOG_INFO("[MAIN] MQTT thread started");
    }
    else
    {
        LOG_INFO("[MAIN] MQTT thread disabled by toggle");
    }

    while (g_running.load(std::memory_order_relaxed))
        std::this_thread::sleep_for(std::chrono::milliseconds(200));

    LOG_INFO("[MAIN] Shutdown requested, stopping services...");

    const auto max_wait = std::chrono::seconds(5);
    const auto poll_interval = std::chrono::milliseconds(100);

    if (ENABLE_RTSP_THREAD)
    {
        RTSPManager::stop();

        if (rtsp_thread.joinable())
            rtsp_thread.join();

        LOG_INFO("[MAIN] RTSP thread finished and joined.");
    }

    auto deadline = std::chrono::steady_clock::now() + max_wait;

    if (ENABLE_MQTT_THREAD)
    {
        while (!mqtt_thread_exited.load(std::memory_order_relaxed) &&
               std::chrono::steady_clock::now() < deadline)
        {
            std::this_thread::sleep_for(poll_interval);
        }

        if (mqtt_thread.joinable())
        {
            if (mqtt_thread_exited.load(std::memory_order_relaxed))
            {
                mqtt_thread.join();
                LOG_INFO("[MAIN] MQTT thread finished and joined.");
            }
            else
            {
                LOG_WARN("[MAIN] MQTT thread did not exit within timeout.");
            }
        }
    }

    bool any_failed = false;
    if (ENABLE_RTSP_THREAD && rtsp_thread.joinable() && !rtsp_thread_exited.load())
        any_failed = true;
    if (ENABLE_MQTT_THREAD && mqtt_thread.joinable() && !mqtt_thread_exited.load())
        any_failed = true;

    if (any_failed)
    {
        LOG_ERROR("[MAIN] Threads did not exit in time. Forcing immediate termination.");
        _exit(1);
    }

    LOG_INFO("[MAIN] Program exited cleanly.");
    return 0;
}
