#include <iostream>
#include <string>
#include <cstdlib>
#include <chrono>
#include <thread>

#include "json/json.h"

const char* DEFAULT_WATCH_DOG_CONFIG_PATH = ETC_PATH"/etc/watch_dog.json";

int main(int argc, char** argv) {
    std::string config_path;
    if (argc > 1) {
        config_path = argv[1];
    }
    else {
        config_path = DEFAULT_WATCH_DOG_CONFIG_PATH;
    }

    Json::Value config_json;
    if (false == ReadJsonFile(config_path, config_json) || !config_json.isMember("config") || !config_json["config"].isArray()) {
        auto time = std::chrono::steady_clock::now();
        std::chrono::duration<double> diff = std::chrono::steady_clock::now() - time;
        while (diff.count() < 10) {
            std::cout << "watch Program is empty!!! after " << 10  - diff.count() << "s, system will restart." << std::endl;
            std::this_thread::sleep_for(std::chrono::seconds(1));
            diff = std::chrono::steady_clock::now() - time;
        }
        system("systemctl reboot");
        exit(-1);
    }

    std::vector<std::string> programs;
    for (int i = 0; i < config_json["config"].size(); i++) {
        programs.push_back(config_json["config"][i]["program"].asString());
    }
    
    int timeout_seconds = 10; // 超时时间（秒）

    while (true) {
        // 检查程序是否存活
        for (int i = 0; i < programs.size(); i++) {
            std::string cmd = "ps aux | grep " + programs[i] + " | grep -v grep";
            if (system(cmd.c_str()) != 0) {
                // 程序已死亡，重启
                std::cout << "Program " << programs[i] << " has died, restarting..." << std::endl;
                system(("pkill -f " + programs[i]).c_str());
                std::this_thread::sleep_for(std::chrono::seconds(1));
                system(("./" + programs[i] + " &").c_str());
            }
        }
        // 等待一段时间后再次检测
        std::this_thread::sleep_for(std::chrono::seconds(timeout_seconds));
    }

    return 0;
}
