#include "router.hpp"
#include "log.hpp"

#include <chrono>
#include <algorithm>

void Router::add_route(const std::string& method, const std::string& path, Handler handler) {
    std::string key = method + " " + path;
    routes_[key] = std::move(handler);
}

void Router::dispatch(tls_session* sess, PairingStore& pairing, const json& config) {
    auto& req  = sess->current_request;
    auto& resp = sess->current_response;

    // Build the full URL path (without host) for query param access
    std::string full_url = req.path;
    if (!req.query_string.empty()) {
        full_url += "?" + req.query_string;
    }

    std::string route_key = req.method + " " + req.path;
    auto it = routes_.find(route_key);
    if (it != routes_.end()) {
        RouteContext ctx;
        ctx.query_path = req.path;
        ctx.full_url = full_url;
        ctx.pairing_store = &pairing;
        ctx.config = config;
        it->second(req, resp, ctx);
        return;
    }

    // 404
    resp.send_json(404, {
        {"Message", "No HTTP resource was found that matches the request URI '" + full_url + "'."}
    });
}

// Init suppression: log only if non-200, slow, or first/different request
// within 30s window. Port of server.js shouldLogInit().
bool Router::should_log_init(const std::string& url, int status, int duration_ms,
                             const std::string& response) {
    // Report suppressed count hourly
    auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch()).count();

    if (suppressed_count_ > 0 && (now - suppressed_report_ts_) > 3'600'000) {
        logc::info("Suppressed %d init log(s) in the last hour", suppressed_count_);
        suppressed_count_ = 0;
        suppressed_report_ts_ = now;
    }

    if (status != 200) return true;
    if (duration_ms > 400) return true;

    int64_t time_since_last = now - last_init_timestamp_;
    if (time_since_last < 30'000 && url == last_init_url_ && response == last_init_result_) {
        last_init_timestamp_ = now;
        suppressed_count_++;
        return false;
    }

    last_init_url_ = url;
    last_init_result_ = response;
    last_init_timestamp_ = now;
    return true;
}
