#include "engine_config.h"

#include <fstream>
#include <sstream>
#include <iostream>
#include <ctime>
#include <unistd.h>

namespace node669427 {

static std::string extract_json_string(const std::string& json, const std::string& key) {
    auto pos = json.find("\"" + key + "\"");
    if (pos == std::string::npos) return "";
    auto colon = json.find(':', pos);
    if (colon == std::string::npos) return "";
    auto start = json.find_first_of("\"", colon + 1);
    if (start == std::string::npos) return "";
    auto end = json.find_first_of("\"", start + 1);
    if (end == std::string::npos) return "";
    return json.substr(start + 1, end - start - 1);
}

static int extract_json_int(const std::string& json, const std::string& key) {
    auto pos = json.find("\"" + key + "\"");
    if (pos == std::string::npos) return 0;
    auto colon = json.find(':', pos);
    if (colon == std::string::npos) return 0;
    auto start = json.find_first_not_of(" \t", colon + 1);
    if (start == std::string::npos) return 0;
    auto end = json.find_first_of(",}\r\n", start);
    if (end == std::string::npos) end = json.size();
    try {
        return std::stoi(json.substr(start, end - start));
    } catch (...) {
        return 0;
    }
}

static std::string extract_nested_json(const std::string& json, const std::string& key) {
    auto pos = json.find("\"" + key + "\"");
    if (pos == std::string::npos) return "";
    auto colon = json.find(':', pos);
    if (colon == std::string::npos) return "";
    auto start = json.find_first_of('{', colon + 1);
    if (start == std::string::npos) return "";
    size_t depth = 1;
    size_t end = start + 1;
    while (end < json.size() && depth > 0) {
        if (json[end] == '{') depth++;
        if (json[end] == '}') depth--;
        end++;
    }
    return json.substr(start, end - start);
}

NodeConfig NodeConfig::load(const std::string& config_path) {
    NodeConfig cfg;
    std::ifstream f(config_path);
    if (!f.is_open()) {
        std::cerr << "[Config] Cannot open " << config_path << std::endl;
        return cfg;
    }
    std::ostringstream ss;
    ss << f.rdbuf();
    std::string json = ss.str();

    cfg.node_id = extract_json_string(json, "node_id");
    cfg.role = extract_json_string(json, "role");
    cfg.listen_port = extract_json_int(json, "listen_port");
    cfg.wg_interface = extract_json_string(json, "wg_interface");
    cfg.shield_ip = extract_json_string(json, "shield_ip");
    cfg.shield_port = extract_json_int(json, "shield_port");
    cfg.vault_path = extract_json_string(json, "vault_path");
    cfg.db_host = extract_json_string(json, "db_host");
    cfg.db_name = extract_json_string(json, "db_name");

    std::string services_json = extract_nested_json(json, "services");
    if (!services_json.empty()) {
        cfg.services.xmr_wallet_url = extract_json_string(services_json, "xmr_wallet_url");
        cfg.services.xmr_daemon_url = extract_json_string(services_json, "xmr_daemon_url");
        cfg.services.tron_signer_url = extract_json_string(services_json, "tron_signer_url");
        cfg.services.stripe_bridge_url = extract_json_string(services_json, "stripe_bridge_url");
        cfg.services.ollama_url = extract_json_string(services_json, "ollama_url");
    }

    return cfg;
}

NodeConfig NodeConfig::from_args(int argc, char* argv[]) {
    NodeConfig cfg;
    std::string config_path = "/etc/apache/engine.conf";

    for (int i = 1; i < argc; ++i) {
        std::string arg = argv[i];
        if (arg == "--node-id" && i + 1 < argc) {
            cfg.node_id = argv[++i];
        } else if (arg == "--role" && i + 1 < argc) {
            cfg.role = argv[++i];
        } else if (arg == "--config" && i + 1 < argc) {
            config_path = argv[++i];
        }
    }

    if (access(config_path.c_str(), R_OK) == 0) {
        NodeConfig file_cfg = load(config_path);
        if (!file_cfg.node_id.empty()) cfg.node_id = file_cfg.node_id;
        if (!file_cfg.role.empty()) cfg.role = file_cfg.role;
        if (file_cfg.listen_port != 0) cfg.listen_port = file_cfg.listen_port;
        if (!file_cfg.vault_path.empty()) cfg.vault_path = file_cfg.vault_path;
        if (!file_cfg.services.xmr_wallet_url.empty()) cfg.services = file_cfg.services;
    }

    return cfg;
}

} // namespace node669427
