#include "crow.h"
#include "routes.h"
#include <chrono>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sys/utsname.h>
#include <unistd.h>

namespace routes {

namespace {

std::string env_or(const char* k, const char* fallback) {
    if (const char* v = std::getenv(k)) return std::string(v);
    return std::string(fallback);
}

long long boot_epoch() {
    static long long boot = std::time(nullptr);
    return boot;
}

} // anonymous namespace

void register_system(crow::SimpleApp& app) {

    // /api/version — build identity
    CROW_ROUTE(app, "/api/version")
    ([]() {
        crow::json::wvalue r;
        r["name"]       = "CxWebApp";
        r["version"]    = env_or("CXWEBAPP_VERSION", "1.1.0");
        r["git_sha"]    = env_or("CXWEBAPP_GIT_SHA", "unknown");
        r["build_time"] = env_or("CXWEBAPP_BUILD_TIME", "");
        return r;
    });

    // /api/system — runtime/system facts (safe to expose, no secrets)
    CROW_ROUTE(app, "/api/system")
    ([]() {
        crow::json::wvalue r;
        struct utsname u{};
        if (uname(&u) == 0) {
            r["sysname"]  = u.sysname;
            r["release"]  = u.release;
            r["machine"]  = u.machine;
            r["nodename"] = u.nodename;
        }
        char host[256] = {0};
        if (gethostname(host, sizeof(host) - 1) == 0) {
            r["hostname"] = std::string(host);
        }
        r["pid"]            = static_cast<long>(::getpid());
        r["uptime_seconds"] = static_cast<long>(std::time(nullptr) - boot_epoch());
        r["cxx_standard"]   = static_cast<int>(__cplusplus);
        return r;
    });

    // /api/echo — POST anything, get it back (debug helper)
    CROW_ROUTE(app, "/api/echo").methods(crow::HTTPMethod::POST)
    ([](const crow::request& req) {
        crow::json::wvalue r;
        r["method"]  = "POST";
        r["len"]     = static_cast<int>(req.body.size());
        r["body"]    = req.body;
        return crow::response(r);
    });

    // /ws/echo — minimal WebSocket echo room (per-connection state)
    CROW_WEBSOCKET_ROUTE(app, "/ws/echo")
        .onopen([](crow::websocket::connection& conn) {
            conn.send_text("welcome");
        })
        .onmessage([](crow::websocket::connection& conn,
                      const std::string& data, bool is_binary) {
            if (is_binary) conn.send_binary(data);
            else           conn.send_text(data);
        })
        .onclose([](crow::websocket::connection&,
                    const std::string&) {});
}

} // namespace routes
