#pragma once

#include <algorithm>
#include <array>
#include <cctype>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <limits>
#include <locale>
#include <map>
#include <optional>
#include <random>
#include <sstream>
#include <stdexcept>
#include <string>
#include <thread>
#include <utility>
#include <vector>
#include <spawn.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

#if defined(__APPLE__)
#include <crt_externs.h>
#endif

#if __has_include(<curl/curl.h>) && !defined(POLARISLINK_NO_LIBCURL)
#define POLARISLINK_HAS_LIBCURL 1
#include <curl/curl.h>
#endif

#if !defined(__APPLE__) && !defined(POLARISLINK_HAS_LIBCURL)
extern char** environ;
#endif

namespace polarislink {

inline constexpr const char* POLARISLINK_SDK_VERSION = "3.1.0";
inline constexpr const char* POLARISLINK_USER_AGENT = "Forticia-PolarisLink-CPP/3.1.0 (Institutional)";
inline constexpr const char* POLARISLINK_LIBRARY = "Forticia PolarisLink™ — C++20 Institutional Client Library (v3.1.0)";
inline constexpr const char* DEFAULT_EQUITY_UNIVERSE = "equities_daily_25y";
inline constexpr const char* DEFAULT_RUN_UNIVERSE = "equities_daily";
inline constexpr int LEASE_TTL_MINUTES_MIN = 5;
inline constexpr int LEASE_TTL_MINUTES_MAX = 720;

inline const std::vector<std::string> RETAIL_PROHIBITED_PROVIDERS = {
    "yfinance", "yahoo", "alphavantage", "finnhub", "polygon_free"
};

class PolarisLinkError : public std::runtime_error {
public:
    PolarisLinkError(long status, std::string code, std::string message, std::string request_id = "",
                     std::optional<double> retry_after = std::nullopt, std::string body = "")
        : std::runtime_error(format(status, code, message, request_id)),
          m_status(status), m_code(std::move(code)), m_message(std::move(message)),
          m_request_id(std::move(request_id)), m_retry_after(retry_after), m_body(std::move(body)) {}

    long status() const noexcept { return m_status; }
    const std::string& code() const noexcept { return m_code; }
    const std::string& message() const noexcept { return m_message; }
    const std::string& request_id() const noexcept { return m_request_id; }
    std::optional<double> retry_after() const noexcept { return m_retry_after; }
    const std::string& body() const noexcept { return m_body; }

private:
    static std::string format(long status, const std::string& code, const std::string& message, const std::string& request_id) {
        std::string out = status > 0 ? "PolarisLink API Error [" + std::to_string(status) + "]: " : "PolarisLink Error: ";
        out += message;
        if (!code.empty() || !request_id.empty()) {
            out += " (";
            if (!code.empty()) out += "code=" + code;
            if (!code.empty() && !request_id.empty()) out += ", ";
            if (!request_id.empty()) out += "request_id=" + request_id;
            out += ")";
        }
        return out;
    }

    long m_status;
    std::string m_code;
    std::string m_message;
    std::string m_request_id;
    std::optional<double> m_retry_after;
    std::string m_body;
};

class TransportError : public PolarisLinkError {
public:
    explicit TransportError(const std::string& message) : PolarisLinkError(0, "transport_error", message) {}
};

class AuthenticationError : public PolarisLinkError { public: using PolarisLinkError::PolarisLinkError; };
class PermissionDeniedError : public PolarisLinkError { public: using PolarisLinkError::PolarisLinkError; };
class NotFoundError : public PolarisLinkError { public: using PolarisLinkError::PolarisLinkError; };
class ConflictError : public PolarisLinkError { public: using PolarisLinkError::PolarisLinkError; };
class RateLimitError : public PolarisLinkError { public: using PolarisLinkError::PolarisLinkError; };
class ServerError : public PolarisLinkError { public: using PolarisLinkError::PolarisLinkError; };
class HarvestPendingError : public PolarisLinkError { public: using PolarisLinkError::PolarisLinkError; };

inline void enforce_institutional_guardrails(const std::string& provider) {
    std::string lower = provider;
    std::transform(lower.begin(), lower.end(), lower.begin(), [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
    for (const auto& prohibited : RETAIL_PROHIBITED_PROVIDERS) {
        if (lower.find(prohibited) != std::string::npos) {
            throw PolarisLinkError(0, "governance_violation",
                "Forticia Quantitative Governance Violation: retail provider '" + provider + "' is prohibited.");
        }
    }
}

inline constexpr double kMissing = std::numeric_limits<double>::quiet_NaN();

struct DailyBar {
    std::string date;
    double open = kMissing;
    double high = kMissing;
    double low = kMissing;
    double close = kMissing;
    double volume = kMissing;
    std::optional<double> ret_1d;
    std::optional<double> overnight_ret;
    bool missing_fields = false;
};

struct OptionQuote {
    std::string contract;
    std::string underlying;
    std::string expiration;
    double strike = kMissing;
    std::string right;
    std::string date;
    std::optional<double> bid;
    std::optional<double> ask;
    std::optional<double> mid;
    std::optional<double> spread;
    double volume = kMissing;
    std::optional<double> iv;
    std::optional<double> delta;
    std::optional<double> gamma;
    std::optional<double> theta;
    std::optional<double> vega;
    std::optional<double> underlying_price;
    std::string data_quality;
    bool missing_fields = false;
};

struct MarketDepthTick {
    uint64_t ts = 0;
    std::string timestamp_iso;
    std::string venue;
    std::string symbol;
    char side = '\0';
    char action = '\0';
    std::string action_desc;
    double price = kMissing;
    double size = kMissing;
    bool missing_fields = false;
};

struct MarketDepthSummary {
    std::string symbol;
    std::string date;
    std::string venue = "CME";
    int total_ticks = 0;
    std::optional<double> best_bid;
    std::optional<double> best_ask;
    std::optional<double> spread;
    std::optional<double> spread_bps;
    std::vector<MarketDepthTick> ticks;
};

struct CorporateBuybackHistoricalStats {
    std::optional<int> evaluated_events;
    double average_alpha_bps = kMissing;
    double excess_over_placebo_bps = kMissing;
    double win_rate_pct = kMissing;
    double profit_factor = kMissing;
};

struct CorporateBuybackProgram {
    std::string symbol;
    std::string company_name;
    double authorized_billions = kMissing;
    double repurchase_yield_pct = kMissing;
    std::string last_earnings_date;
    std::string blackout_lift_date;
    std::string execution_window_end;
    std::string status;
    std::optional<int> days_until_lift;
    std::optional<int> days_remaining_in_window;
    CorporateBuybackHistoricalStats historical_stats;
    bool missing_fields = false;
};

struct CorporateBuybackResponse {
    std::string as_of_date;
    int active_programs_count = 0;
    int current_window_active_count = 0;
    std::string rule_of_law = "SEC Rule 10b-18 Safe Harbor (17 CFR § 240.10b-18)";
    std::string universe;
    std::string data_quality = "unreported";
    bool quotes_verified = false;
    std::vector<CorporateBuybackProgram> programs;
};

struct BacktestRunMetrics {
    std::string strategy_name;
    std::string workspace_id = "blitz";
    std::string universe = DEFAULT_RUN_UNIVERSE;
    std::string start_date;
    std::string end_date;
    std::optional<double> sharpe;
    std::optional<double> cagr;
    std::optional<double> max_drawdown;
    int trades_count = 0;
    std::optional<double> win_rate;
    std::string git_commit;
    std::string provenance_hash;
    std::string metrics_json = "{}";
};

struct TelemetryStatus {
    std::string status;
    std::string gateway;
    std::string node;
    std::string protocol_version;
    int uptime_seconds = 0;
    int runs_recorded = 0;
};

struct GovernanceKnowledge {
    bool zero_bad_data_enforced = true;
    std::vector<std::string> prohibited_vendors;
    std::vector<std::string> available_universes;
};

struct HttpResponse {
    long status = 0;
    std::string body;
    std::map<std::string, std::string> headers;

    std::string header(const std::string& name) const {
        std::string key = name;
        std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
        auto it = headers.find(key);
        return it == headers.end() ? std::string() : it->second;
    }
    bool ok() const { return status >= 200 && status < 300; }
};

class Query {
public:
    Query& add(const std::string& key, const std::string& value) {
        if (!value.empty()) m_items.emplace_back(key, value);
        return *this;
    }
    Query& add(const std::string& key, const char* value) { return add(key, std::string(value ? value : "")); }
    Query& add(const std::string& key, long long value) { m_items.emplace_back(key, std::to_string(value)); return *this; }
    Query& add(const std::string& key, int value) { return add(key, static_cast<long long>(value)); }
    Query& add_if(const std::string& key, long long value, bool include) {
        if (include) add(key, value);
        return *this;
    }

    std::string str() const {
        std::string out;
        for (const auto& [k, v] : m_items) {
            out += out.empty() ? "?" : "&";
            out += encode(k) + "=" + encode(v);
        }
        return out;
    }

    static std::string encode(const std::string& value) {
        static const char* hex = "0123456789ABCDEF";
        std::string out;
        out.reserve(value.size() * 3);
        for (unsigned char c : value) {
            if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
                out.push_back(static_cast<char>(c));
            } else {
                out.push_back('%');
                out.push_back(hex[c >> 4]);
                out.push_back(hex[c & 0x0F]);
            }
        }
        return out;
    }

private:
    std::vector<std::pair<std::string, std::string>> m_items;
};

class CsvTable {
public:
    explicit CsvTable(const std::string& text) {
        std::istringstream stream(text);
        std::string line;
        bool header = true;
        while (std::getline(stream, line)) {
            while (!line.empty() && (line.back() == '\r' || line.back() == '\n')) line.pop_back();
            if (line.empty()) continue;
            auto cols = split(line);
            if (header) {
                for (size_t i = 0; i < cols.size(); ++i) m_index[cols[i]] = i;
                header = false;
                continue;
            }
            m_rows.push_back(std::move(cols));
        }
    }

    const std::vector<std::vector<std::string>>& rows() const { return m_rows; }

    std::string text(const std::vector<std::string>& row, const std::string& column) const {
        auto it = m_index.find(column);
        if (it == m_index.end() || it->second >= row.size()) return "";
        return row[it->second];
    }

    std::optional<double> number(const std::vector<std::string>& row, const std::string& column) const {
        return parse_number(text(row, column));
    }

    static std::optional<double> parse_number(const std::string& raw) {
        std::string s = raw;
        while (!s.empty() && std::isspace(static_cast<unsigned char>(s.back()))) s.pop_back();
        size_t start = 0;
        while (start < s.size() && std::isspace(static_cast<unsigned char>(s[start]))) ++start;
        s = s.substr(start);
        if (s.empty() || s == "null" || s == "NaN" || s == "nan" || s == "None") return std::nullopt;
        char* end = nullptr;
        double v = std::strtod(s.c_str(), &end);
        if (end == s.c_str() || *end != '\0' || !std::isfinite(v)) return std::nullopt;
        return v;
    }

    static std::vector<std::string> split(const std::string& line) {
        std::vector<std::string> fields;
        std::string field;
        bool quoted = false;
        for (size_t i = 0; i < line.size(); ++i) {
            char c = line[i];
            if (quoted) {
                if (c == '"' && i + 1 < line.size() && line[i + 1] == '"') {
                    field.push_back('"');
                    ++i;
                } else if (c == '"') {
                    quoted = false;
                } else {
                    field.push_back(c);
                }
            } else if (c == '"') {
                quoted = true;
            } else if (c == ',') {
                fields.push_back(field);
                field.clear();
            } else {
                field.push_back(c);
            }
        }
        fields.push_back(field);
        return fields;
    }

private:
    std::map<std::string, size_t> m_index;
    std::vector<std::vector<std::string>> m_rows;
};

class Client {
public:
    explicit Client(std::string api_key = "", std::string base_url = "") {
        if (api_key.empty()) {
            const char* env_key = std::getenv("FORTICIA_API_KEY");
            m_api_key = env_key ? env_key : "";
        } else {
            m_api_key = std::move(api_key);
        }
        if (base_url.empty()) {
            const char* env_url = std::getenv("FORTICIA_API_URL");
            m_base_url = env_url ? env_url : "https://forticia.uk";
        } else {
            m_base_url = std::move(base_url);
        }
        while (!m_base_url.empty() && m_base_url.back() == '/') m_base_url.pop_back();
    }

    void set_max_retries(int retries) { m_max_retries = std::max(0, retries); }
    void set_timeout_seconds(long seconds) { m_timeout_seconds = std::max(1L, seconds); }

    HttpResponse request(const std::string& method, const std::string& path, const std::string& body = "",
                         const std::string& accept = "application/json") {
        HttpResponse res = send_with_retry(method, path, body, accept);
        if (!res.ok()) throw_for(res);
        if (res.status == 202 && res.body.find("\"status\":\"harvesting") != std::string::npos) {
            throw HarvestPendingError(202, "harvest_pending", extract_json_string(res.body, "message"),
                                      res.header("x-request-id"), parse_retry_after(res.header("retry-after")), res.body);
        }
        return res;
    }

    TelemetryStatus get_telemetry() {
        std::string raw = request("GET", "/api/polarislink/telemetry").body;
        TelemetryStatus t;
        t.status = extract_json_string(raw, "status");
        t.gateway = extract_json_string(raw, "gateway");
        t.node = extract_json_string(raw, "node");
        t.protocol_version = extract_json_string(raw, "protocolVersion");
        auto uptime = CsvTable::parse_number(extract_json_scalar(raw, "uptimeSeconds"));
        if (uptime) t.uptime_seconds = static_cast<int>(*uptime);
        return t;
    }

    GovernanceKnowledge get_knowledge() {
        std::string raw = request("GET", "/api/polarislink/knowledge").body;
        GovernanceKnowledge k;
        k.zero_bad_data_enforced = raw.find("\"zeroBadDataMandate\"") != std::string::npos;
        k.prohibited_vendors = RETAIL_PROHIBITED_PROVIDERS;
        return k;
    }

    std::string log_run(const BacktestRunMetrics& r) {
        if (r.strategy_name.empty()) {
            throw std::invalid_argument("Strategy name is required to log backtest run.");
        }
        std::ostringstream json;
        json << "{"
             << "\"strategyName\":" << quote(r.strategy_name) << ","
             << "\"workspaceId\":" << quote(r.workspace_id) << ","
             << "\"universe\":" << quote(r.universe) << ","
             << "\"gitCommit\":" << quote(r.git_commit) << ","
             << "\"provenanceHash\":" << quote(r.provenance_hash) << ","
             << "\"tradesCount\":" << r.trades_count;
        if (!r.start_date.empty()) json << ",\"startDate\":" << quote(r.start_date);
        if (!r.end_date.empty()) json << ",\"endDate\":" << quote(r.end_date);
        if (r.sharpe) json << ",\"sharpe\":" << number(*r.sharpe);
        if (r.cagr) json << ",\"cagr\":" << number(*r.cagr);
        if (r.max_drawdown) json << ",\"maxDrawdown\":" << number(*r.max_drawdown);
        if (r.win_rate) json << ",\"winRate\":" << number(*r.win_rate);
        if (!r.metrics_json.empty()) json << ",\"metrics\":" << r.metrics_json;
        json << "}";
        std::string response = request("POST", "/api/polarislink/runs", json.str()).body;
        std::string id = extract_json_string(response, "id");
        return id.empty() ? extract_json_scalar(response, "id") : id;
    }

    bool report_issue(const std::string& title, const std::string& description, const std::string& category = "Data Gap",
                      const std::string& priority = "Normal", const std::string& workspace = "blitz") {
        std::ostringstream json;
        json << "{"
             << "\"title\":" << quote(title) << ","
             << "\"description\":" << quote(description) << ","
             << "\"category\":" << quote(category) << ","
             << "\"priority\":" << quote(priority) << ","
             << "\"workspace\":" << quote(workspace)
             << "}";
        return state_change("POST", "/api/polarislink/issues", json.str());
    }

    std::vector<DailyBar> get_bars(const std::string& symbol, const std::string& universe = DEFAULT_EQUITY_UNIVERSE,
                                   const std::string& start = "", const std::string& end = "", int limit = 0,
                                   int page_size = 10000) {
        std::vector<DailyBar> bars;
        long long offset = 0;
        while (true) {
            int remaining = limit > 0 ? limit - static_cast<int>(bars.size()) : page_size;
            if (remaining <= 0) break;
            int page_limit = std::min(page_size, remaining);
            Query q;
            q.add("symbol", symbol).add("universe", universe).add("format", "csv")
             .add("limit", page_limit).add("offset", offset).add("start", start).add("end", end);
            HttpResponse res = request("GET", "/api/polarislink/quant/bars" + q.str(), "", "text/csv");
            CsvTable table(res.body);
            for (const auto& row : table.rows()) {
                DailyBar b;
                b.date = table.text(row, "date");
                assign(b.open, table.number(row, "open"), b.missing_fields);
                assign(b.high, table.number(row, "high"), b.missing_fields);
                assign(b.low, table.number(row, "low"), b.missing_fields);
                assign(b.close, table.number(row, "close"), b.missing_fields);
                assign(b.volume, table.number(row, "volume"), b.missing_fields);
                b.ret_1d = table.number(row, "ret_1d");
                b.overnight_ret = table.number(row, "overnight_ret");
                bars.push_back(std::move(b));
            }
            long long page_rows = static_cast<long long>(table.rows().size());
            offset += page_rows;
            auto total = CsvTable::parse_number(res.header("x-total-bars"));
            if (page_rows < page_limit || page_rows == 0) break;
            if (total && offset >= static_cast<long long>(*total)) break;
        }
        return bars;
    }

    std::vector<OptionQuote> get_options_surface(const std::string& symbol = "SPX") {
        Query q;
        q.add("symbol", symbol).add("format", "csv");
        CsvTable table(request("GET", "/api/polarislink/quant/options/surface" + q.str(), "", "text/csv").body);
        std::vector<OptionQuote> quotes;
        for (const auto& row : table.rows()) quotes.push_back(parse_quote(table, row));
        return quotes;
    }

    std::vector<OptionQuote> get_options_history(const std::string& symbol = "SPX", const std::string& contract = "",
                                                 const std::string& expiration = "", const std::string& start = "",
                                                 const std::string& end = "", int limit = 10000) {
        Query q;
        q.add("symbol", symbol).add("format", "csv").add("limit", limit)
         .add("contract", contract).add("expiration", expiration).add("start", start).add("end", end);
        CsvTable table(request("GET", "/api/polarislink/quant/options/history" + q.str(), "", "text/csv").body);
        std::vector<OptionQuote> quotes;
        for (const auto& row : table.rows()) quotes.push_back(parse_quote(table, row));
        return quotes;
    }

    std::vector<MarketDepthTick> get_market_depth(const std::string& symbol, const std::string& date = "", int limit = 500) {
        Query q;
        q.add("symbol", symbol).add("format", "csv").add("limit", limit).add("date", date);
        CsvTable table(request("GET", "/api/polarislink/quant/depth" + q.str(), "", "text/csv").body);
        std::vector<MarketDepthTick> ticks;
        for (const auto& row : table.rows()) {
            MarketDepthTick t;
            auto ts = table.number(row, "ts");
            if (ts) {
                t.ts = static_cast<uint64_t>(*ts);
            } else {
                t.missing_fields = true;
            }
            t.timestamp_iso = table.text(row, "timestampIso");
            t.venue = table.text(row, "venue");
            t.symbol = table.text(row, "symbol");
            std::string side = table.text(row, "side");
            std::string action = table.text(row, "action");
            if (side.empty()) t.missing_fields = true; else t.side = side[0];
            if (action.empty()) t.missing_fields = true; else t.action = action[0];
            t.action_desc = table.text(row, "actionDesc");
            assign(t.price, table.number(row, "price"), t.missing_fields);
            assign(t.size, table.number(row, "size"), t.missing_fields);
            ticks.push_back(std::move(t));
        }
        return ticks;
    }

    CorporateBuybackResponse get_buybacks(const std::string& symbol = "", const std::string& status = "") {
        Query q;
        q.add("format", "csv").add("symbol", symbol).add("status", status);
        CsvTable table(request("GET", "/api/polarislink/quant/buybacks" + q.str(), "", "text/csv").body);
        CorporateBuybackResponse response;
        for (const auto& row : table.rows()) {
            CorporateBuybackProgram prog;
            prog.symbol = table.text(row, "symbol");
            prog.company_name = table.text(row, "companyName");
            assign(prog.authorized_billions, table.number(row, "authorizedBillions"), prog.missing_fields);
            assign(prog.repurchase_yield_pct, table.number(row, "repurchaseYieldPct"), prog.missing_fields);
            prog.last_earnings_date = table.text(row, "lastEarningsDate");
            prog.blackout_lift_date = table.text(row, "blackoutLiftDate");
            prog.execution_window_end = table.text(row, "executionWindowEnd");
            prog.status = table.text(row, "status");
            prog.days_until_lift = to_int(table.number(row, "daysUntilLift"));
            prog.days_remaining_in_window = to_int(table.number(row, "daysRemainingInWindow"));
            prog.historical_stats.evaluated_events = to_int(table.number(row, "evaluatedEvents"));
            assign(prog.historical_stats.average_alpha_bps, table.number(row, "averageAlphaBps"), prog.missing_fields);
            assign(prog.historical_stats.excess_over_placebo_bps, table.number(row, "excessOverPlaceboBps"), prog.missing_fields);
            assign(prog.historical_stats.win_rate_pct, table.number(row, "winRatePct"), prog.missing_fields);
            assign(prog.historical_stats.profit_factor, table.number(row, "profitFactor"), prog.missing_fields);
            if (!prog.days_until_lift || !prog.days_remaining_in_window || !prog.historical_stats.evaluated_events) {
                prog.missing_fields = true;
            }
            if (prog.status == "active_window") response.current_window_active_count++;
            response.programs.push_back(std::move(prog));
        }
        response.active_programs_count = static_cast<int>(response.programs.size());
        return response;
    }

    struct SwarmLeaseResult {
        std::string status;
        std::string frontier_id;
        std::string node_id;
        std::string expires_at;
        int ttl_seconds = 0;
        int ttl_minutes = 0;
        bool is_conflict = false;
        std::string held_by;
        int remaining_seconds = 0;
        long http_status = 0;
        std::string message;
    };

    static int ttl_seconds_to_minutes(int ttl_seconds) {
        int minutes = ttl_seconds <= 0 ? 0 : (ttl_seconds + 59) / 60;
        return std::clamp(minutes, LEASE_TTL_MINUTES_MIN, LEASE_TTL_MINUTES_MAX);
    }

    SwarmLeaseResult claim_lease(const std::string& node_id, const std::string& frontier_id, int ttl_seconds = 7200,
                                 const std::string& swarm_id = "blitz") {
        return claim_lease_minutes(node_id, frontier_id, ttl_seconds_to_minutes(ttl_seconds), swarm_id);
    }

    SwarmLeaseResult claim_lease_minutes(const std::string& node_id, const std::string& frontier_id, int ttl_minutes = 120,
                                         const std::string& swarm_id = "blitz", const std::string& assigned_domain = "") {
        int minutes = std::clamp(ttl_minutes, LEASE_TTL_MINUTES_MIN, LEASE_TTL_MINUTES_MAX);
        std::ostringstream json;
        json << "{"
             << "\"nodeId\":" << quote(node_id) << ","
             << "\"frontierId\":" << quote(frontier_id) << ","
             << "\"ttlMinutes\":" << minutes;
        if (!assigned_domain.empty()) json << ",\"assignedDomain\":" << quote(assigned_domain);
        json << "}";
        HttpResponse res = send_with_retry("POST", swarm_path(swarm_id, "/leases/claim"), json.str(), "application/json");
        SwarmLeaseResult out;
        out.http_status = res.status;
        out.frontier_id = frontier_id;
        out.node_id = node_id;
        if (res.status == 409) {
            out.status = "conflict";
            out.is_conflict = true;
            out.message = extract_json_string(res.body, "message");
            out.held_by = extract_json_string(res.body, "heldBy");
            if (out.held_by.empty()) {
                auto open = out.message.find('[');
                auto close = out.message.find(']', open == std::string::npos ? 0 : open);
                if (open != std::string::npos && close != std::string::npos) out.held_by = out.message.substr(open + 1, close - open - 1);
            }
            return out;
        }
        if (!res.ok()) throw_for(res);
        out.status = "claimed";
        out.message = extract_json_string(res.body, "message");
        out.expires_at = extract_json_scalar(res.body, "expiresAt");
        auto ttl = CsvTable::parse_number(extract_json_scalar(res.body, "ttlMinutes"));
        out.ttl_minutes = ttl ? static_cast<int>(*ttl) : minutes;
        out.ttl_seconds = out.ttl_minutes * 60;
        return out;
    }

    bool release_lease(const std::string& node_id, const std::string& frontier_id, bool completed = false,
                       const std::string& summary = "", const std::string& swarm_id = "blitz") {
        std::ostringstream json;
        json << "{"
             << "\"nodeId\":" << quote(node_id) << ","
             << "\"frontierId\":" << quote(frontier_id) << ","
             << "\"markCompleted\":" << (completed ? "true" : "false");
        if (!summary.empty()) json << ",\"summary\":" << quote(summary);
        json << "}";
        return state_change("POST", swarm_path(swarm_id, "/leases/release"), json.str());
    }

    bool send_heartbeat(const std::string& node_id, const std::string& swarm_id = "blitz", const std::string& status = "",
                        const std::string& workload_summary = "", const std::string& cpu_load = "",
                        const std::string& active_hypothesis = "") {
        std::ostringstream json;
        json << "{\"nodeId\":" << quote(node_id);
        if (!status.empty()) json << ",\"status\":" << quote(status);
        if (!workload_summary.empty()) json << ",\"workloadSummary\":" << quote(workload_summary);
        if (!cpu_load.empty()) json << ",\"cpuLoad\":" << quote(cpu_load);
        if (!active_hypothesis.empty()) json << ",\"activeHypothesis\":" << quote(active_hypothesis);
        json << "}";
        return state_change("POST", swarm_path(swarm_id, "/heartbeat"), json.str());
    }

    bool broadcast_scar(const std::string& scar_id, const std::string& title, const std::string& mechanism,
                        const std::string& root_cause, const std::string& rule, const std::string& source_node = "",
                        const std::string& swarm_id = "blitz", const std::string& author = "") {
        std::ostringstream json;
        json << "{"
             << "\"scarId\":" << quote(scar_id) << ","
             << "\"title\":" << quote(title) << ","
             << "\"mechanism\":" << quote(mechanism) << ","
             << "\"rootCause\":" << quote(root_cause) << ","
             << "\"rule\":" << quote(rule);
        if (!source_node.empty()) json << ",\"sourceNode\":" << quote(source_node);
        if (!author.empty()) json << ",\"author\":" << quote(author);
        json << "}";
        return state_change("POST", swarm_path(swarm_id, "/scars"), json.str());
    }

    std::string get_swarm_status(const std::string& swarm_id = "blitz") {
        return request("GET", swarm_path(swarm_id, "/status")).body;
    }

    std::string replenish_frontier_wave(const std::string& wave_name = "Wave 2 — Cross-Asset & Volatility Surface Frontiers",
                                        const std::string& target_universe = "US_EQUITIES_SP500_OPTIONS_CBOE_CME",
                                        int min_frontiers = 50, bool pre_screen_against_scars = true,
                                        const std::string& swarm_id = "blitz") {
        std::ostringstream json;
        json << "{\"minFrontiers\":" << min_frontiers
             << ",\"preScreenAgainstScars\":" << (pre_screen_against_scars ? "true" : "false");
        if (!wave_name.empty()) json << ",\"waveName\":" << quote(wave_name);
        if (!target_universe.empty()) json << ",\"targetUniverse\":" << quote(target_universe);
        json << "}";
        return request("POST", swarm_path(swarm_id, "/frontiers/replenish"), json.str()).body;
    }

    [[deprecated("use replenish_frontier_wave(wave_name, target_universe, min_frontiers, pre_screen, swarm_id)")]]
    std::string replenish_frontier_waves(int count = 50, const std::string& wave_id = "", const std::string& swarm_id = "blitz") {
        return replenish_frontier_wave(wave_id, "", count, true, swarm_id);
    }

    std::string batch_register_frontiers(const std::string& frontiers_json_array, bool pre_screen_against_scars = true,
                                         const std::string& swarm_id = "blitz") {
        std::ostringstream json;
        json << "{\"frontiers\":" << frontiers_json_array
             << ",\"preScreenAgainstScars\":" << (pre_screen_against_scars ? "true" : "false") << "}";
        return request("POST", swarm_path(swarm_id, "/frontiers/batch"), json.str()).body;
    }

    std::string batch_register_frontiers(const std::string& frontiers_json, const std::string& swarm_id) {
        return batch_register_frontiers(frontiers_json, true, swarm_id);
    }

    std::string batch_register_frontiers(const std::string& frontiers_json, const char* swarm_id) {
        return batch_register_frontiers(frontiers_json, true, std::string(swarm_id ? swarm_id : "blitz"));
    }

    std::string get_frontier_catalog_stats(const std::string& swarm_id = "blitz") {
        return request("GET", swarm_path(swarm_id, "/frontiers/catalog-stats")).body;
    }

    std::string list_frontier_waves(const std::string& swarm_id = "blitz") {
        return request("GET", swarm_path(swarm_id, "/waves")).body;
    }

    std::string get_swarm_leases(const std::string& swarm_id = "blitz") {
        return request("GET", swarm_path(swarm_id, "/leases")).body;
    }

    std::string list_swarm_discoveries(const std::string& status = "", const std::string& domain = "", int limit = 50,
                                       const std::string& swarm_id = "blitz") {
        Query q;
        q.add("limit", limit).add("status", status).add("domain", domain);
        return request("GET", swarm_path(swarm_id, "/discoveries") + q.str()).body;
    }

    std::string get_spec(const std::string& format = "json") {
        if (format == "markdown" || format == "md") {
            return request("GET", "/api/polarislink/spec?format=markdown", "", "text/markdown").body;
        }
        return request("GET", "/api/polarislink/spec").body;
    }

    std::string get_changelog(const std::string& format = "json") {
        if (format == "markdown" || format == "md") {
            return request("GET", "/api/polarislink/changelog?format=markdown", "", "text/markdown").body;
        }
        return request("GET", "/api/polarislink/changelog").body;
    }

    std::string get_reports(const std::string& report_type = "") {
        Query q;
        q.add("type", report_type);
        return request("GET", "/api/polarislink/reports" + q.str()).body;
    }

    std::string get_notifications() {
        return request("GET", "/api/polarislink/notifications").body;
    }

    std::string update_notifications(const std::string& json_payload) {
        return request("PUT", "/api/polarislink/notifications", json_payload).body;
    }

    std::string get_cross_audit_queue(const std::string& domain = "", const std::string& exclude_node_id = "", int limit = 50,
                                      const std::string& swarm_id = "blitz") {
        Query q;
        q.add("limit", limit).add("domain", domain).add("excludeNodeId", exclude_node_id);
        return request("GET", swarm_path(swarm_id, "/cross-audit/queue") + q.str()).body;
    }

    std::string get_audits_queue(const std::string& domain = "", const std::string& exclude_node_id = "", int limit = 50,
                                 const std::string& swarm_id = "blitz") {
        Query q;
        q.add("limit", limit).add("domain", domain).add("excludeNodeId", exclude_node_id);
        return request("GET", swarm_path(swarm_id, "/audits") + q.str()).body;
    }

    std::string get_portfolio_manifest(const std::string& swarm_id = "blitz") {
        Query q;
        q.add("swarm", swarm_id);
        return request("GET", "/api/polarislink/quant/manifest" + q.str()).body;
    }

    std::string sync_portfolio_manifest(const std::string& manifest_json, const std::string& mode = "replace",
                                        const std::string& swarm_id = "blitz") {
        Query q;
        q.add("swarm", swarm_id).add("mode", mode);
        return request("POST", "/api/polarislink/quant/manifest/sync" + q.str(), manifest_json).body;
    }

    std::string get_quant_summary(const std::string& swarm_id = "blitz") {
        Query q;
        q.add("swarm", swarm_id);
        return request("GET", "/api/polarislink/quant/summary" + q.str()).body;
    }

    std::string get_borrow_curves(const std::string& symbol = "") {
        Query q;
        q.add("symbol", symbol);
        return request("GET", "/api/polarislink/quant/borrow" + q.str()).body;
    }

    std::string submit_disposition_audit(const std::string& disposition_id, const std::string& verdict_json,
                                         const std::string& swarm_id = "blitz") {
        return request("POST", swarm_path(swarm_id, "/dispositions/" + Query::encode(disposition_id) + "/audit"), verdict_json).body;
    }

    [[deprecated("use submit_disposition_audit(disposition_id, verdict_json, swarm_id)")]]
    std::string submit_cross_audit_verdict(const std::string& disposition_id, const std::string& verdict_json) {
        return submit_disposition_audit(disposition_id, verdict_json);
    }

    std::string orthogonalize_alpha(const std::string& payload_json, const std::string& swarm_id = "blitz") {
        return request("POST", swarm_path(swarm_id, "/orthogonalize"), payload_json).body;
    }

    std::string claim_cross_audit(const std::string& frontier_id, const std::string& auditor_node_id,
                                  [[maybe_unused]] const std::string& auditor_researcher = "", int ttl_minutes = 60,
                                  const std::string& swarm_id = "blitz") {
        std::ostringstream json;
        json << "{"
             << "\"frontierId\":" << quote(frontier_id) << ","
             << "\"nodeId\":" << quote(auditor_node_id) << ","
             << "\"ttlMinutes\":" << ttl_minutes
             << "}";
        return request("POST", swarm_path(swarm_id, "/cross-audit/claim"), json.str()).body;
    }

    std::string submit_cross_audit_verdict(const std::string& audit_id, [[maybe_unused]] const std::string& frontier_id,
                                           const std::string& auditor_node_id, const std::string& verdict,
                                           std::optional<double> replication_sharpe_is = std::nullopt,
                                           std::optional<double> replication_sharpe_oos = std::nullopt,
                                           std::optional<int> replication_sample_size = std::nullopt,
                                           std::optional<double> mae_bps = std::nullopt, const std::string& notes = "",
                                           const std::string& swarm_id = "blitz") {
        std::ostringstream json;
        json << "{"
             << "\"auditId\":" << quote(audit_id) << ","
             << "\"nodeId\":" << quote(auditor_node_id) << ","
             << "\"verdict\":" << quote(verdict);
        if (replication_sharpe_is) json << ",\"replicationSharpeIs\":" << number(*replication_sharpe_is);
        if (replication_sharpe_oos) json << ",\"replicationSharpeOos\":" << number(*replication_sharpe_oos);
        if (replication_sample_size) json << ",\"replicationSampleSize\":" << *replication_sample_size;
        if (mae_bps) json << ",\"maeBps\":" << number(*mae_bps);
        if (!notes.empty()) json << ",\"notes\":" << quote(notes);
        json << "}";
        return request("POST", swarm_path(swarm_id, "/cross-audit/verdict"), json.str()).body;
    }

    std::string submit_execution_intent(const std::string& json_payload) {
        return request("POST", "/api/polarislink/execution/intents", json_payload).body;
    }

    std::string get_crossing_book() {
        return request("GET", "/api/polarislink/execution/crossing").body;
    }

    std::string get_fills(const std::string& symbol = "", int limit = 100) {
        Query q;
        q.add("limit", limit).add("symbol", symbol);
        return request("GET", "/api/polarislink/execution/fills" + q.str()).body;
    }

    std::string get_tca(const std::string& fill_id) {
        return request("GET", "/api/polarislink/execution/tca/" + Query::encode(fill_id)).body;
    }

    std::string get_locates(const std::string& symbol = "") {
        Query q;
        q.add("symbol", symbol);
        return request("GET", "/api/polarislink/risk/locates" + q.str()).body;
    }

    std::string get_risk_limits() {
        return request("GET", "/api/polarislink/risk/limits").body;
    }

    std::string get_features_catalog(const std::string& domain = "") {
        Query q;
        q.add("category", domain);
        return request("GET", "/api/polarislink/features/catalog" + q.str()).body;
    }

    std::string get_feature_series(const std::string& feature_id, const std::string& symbol = "SPY", int limit = 1000) {
        Query q;
        q.add("featureId", feature_id).add("symbol", symbol).add("limit", limit);
        return request("GET", "/api/polarislink/features/series" + q.str()).body;
    }

    std::string orthogonalize_alpha(const std::string& challenger_id, const std::vector<double>& challenger_vector,
                                    const std::string& incumbent_id, const std::vector<double>& incumbent_vector,
                                    double threshold_ir = 1.0, const std::string& swarm_id = "blitz") {
        std::ostringstream json;
        json << "{\"challengerStrategyId\":" << quote(challenger_id) << ",\"challengerVector\":" << number_array(challenger_vector)
             << ",\"incumbentStrategyId\":" << quote(incumbent_id) << ",\"incumbentVector\":" << number_array(incumbent_vector)
             << ",\"thresholdIr\":" << number(threshold_ir) << "}";
        return request("POST", swarm_path(swarm_id, "/orthogonalize"), json.str()).body;
    }

    std::string get_impact_surface(const std::string& universe = "") {
        Query q;
        q.add("universe", universe);
        return request("GET", "/api/polarislink/quant/impact-surface" + q.str()).body;
    }

    std::string get_macro_events(const std::string& event_name = "", const std::string& category = "", int64_t as_of_knowledge = -1) {
        Query q;
        q.add("eventName", event_name).add("category", category).add_if("asOfKnowledge", as_of_knowledge, as_of_knowledge >= 0);
        return request("GET", "/api/polarislink/quant/macro/events" + q.str()).body;
    }

    std::string get_cftc_positioning(const std::string& contract = "", int64_t as_of_knowledge = -1) {
        Query q;
        q.add("contract", contract).add_if("asOfKnowledge", as_of_knowledge, as_of_knowledge >= 0);
        return request("GET", "/api/polarislink/quant/positioning/cot" + q.str()).body;
    }

    std::string get_options_gex(const std::string& symbol = "SPX", const std::string& as_of_date = "", int64_t as_of_knowledge = -1) {
        Query q;
        q.add("symbol", symbol).add("asOfDate", as_of_date).add_if("asOfKnowledge", as_of_knowledge, as_of_knowledge >= 0);
        return request("GET", "/api/polarislink/quant/options/gex" + q.str()).body;
    }

    std::string resolve_symbology(const std::string& ticker = "", const std::string& canonical_id = "") {
        Query q;
        q.add("ticker", ticker).add("canonicalId", canonical_id);
        return request("GET", "/api/polarislink/quant/symbology/resolve" + q.str()).body;
    }

    std::string get_continuous_futures(const std::string& contract_root = "") {
        Query q;
        q.add("root", contract_root);
        return request("GET", "/api/polarislink/quant/futures/continuous" + q.str()).body;
    }

    std::string get_discrete_futures_contracts(const std::string& contracts = "", const std::string& tenor = "") {
        Query q;
        q.add("contracts", contracts).add("tenor", tenor);
        return request("GET", "/api/polarislink/futures/contracts" + q.str()).body;
    }

    std::string get_futures_bars(const std::string& symbol = "", const std::string& tenor = "", const std::string& start = "",
                                 const std::string& end = "", int limit = 1000, const std::string& format = "json") {
        Query q;
        q.add("symbol", symbol).add("tenor", tenor).add("start", start).add("end", end).add("limit", limit).add("format", format);
        return request("GET", "/api/polarislink/quant/futures/bars" + q.str(), "", format == "csv" ? "text/csv" : "application/json").body;
    }

    std::string get_borrow_fee_curves(const std::string& symbol = "", const std::string& as_of_date = "") {
        Query q;
        q.add("symbol", symbol).add("asOfDate", as_of_date);
        return request("GET", "/api/polarislink/quant/borrow-curves" + q.str()).body;
    }

    static std::string extract_json_string(const std::string& json, const std::string& key) {
        std::string search = "\"" + key + "\":";
        auto pos = json.find(search);
        if (pos == std::string::npos) return "";
        pos += search.length();
        while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) ++pos;
        if (pos >= json.size() || json[pos] != '"') return "";
        std::string out;
        for (++pos; pos < json.size(); ++pos) {
            char c = json[pos];
            if (c == '\\' && pos + 1 < json.size()) {
                char n = json[++pos];
                switch (n) {
                    case 'n': out.push_back('\n'); break;
                    case 't': out.push_back('\t'); break;
                    case 'r': out.push_back('\r'); break;
                    case 'b': out.push_back('\b'); break;
                    case 'f': out.push_back('\f'); break;
                    default: out.push_back(n); break;
                }
                continue;
            }
            if (c == '"') break;
            out.push_back(c);
        }
        return out;
    }

    static std::string extract_json_scalar(const std::string& json, const std::string& key) {
        std::string search = "\"" + key + "\":";
        auto pos = json.find(search);
        if (pos == std::string::npos) return "";
        pos += search.length();
        while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) ++pos;
        if (pos < json.size() && json[pos] == '"') return extract_json_string(json, key);
        auto end = json.find_first_of(",}]", pos);
        std::string raw = json.substr(pos, end == std::string::npos ? std::string::npos : end - pos);
        while (!raw.empty() && std::isspace(static_cast<unsigned char>(raw.back()))) raw.pop_back();
        return raw == "null" ? "" : raw;
    }

    static std::string escape_json(const std::string& s) {
        std::ostringstream o;
        for (unsigned char c : s) {
            switch (c) {
                case '"': o << "\\\""; break;
                case '\\': o << "\\\\"; break;
                case '\b': o << "\\b"; break;
                case '\f': o << "\\f"; break;
                case '\n': o << "\\n"; break;
                case '\r': o << "\\r"; break;
                case '\t': o << "\\t"; break;
                default:
                    if (c < 0x20) {
                        o << "\\u" << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(c) << std::dec << std::setfill(' ');
                    } else {
                        o << static_cast<char>(c);
                    }
            }
        }
        return o.str();
    }

private:
    std::string m_api_key;
    std::string m_base_url;
    int m_max_retries = 3;
    long m_timeout_seconds = 60;

    static std::string quote(const std::string& s) { return "\"" + escape_json(s) + "\""; }

    static std::string number(double v) {
        if (!std::isfinite(v)) return "null";
        std::ostringstream o;
        o.imbue(std::locale::classic());
        o << std::setprecision(17) << v;
        return o.str();
    }

    static std::string number_array(const std::vector<double>& values) {
        std::string out = "[";
        for (size_t i = 0; i < values.size(); ++i) {
            if (i > 0) out += ",";
            out += number(values[i]);
        }
        return out + "]";
    }

    static void assign(double& target, const std::optional<double>& value, bool& missing) {
        if (value) {
            target = *value;
        } else {
            target = kMissing;
            missing = true;
        }
    }

    static std::optional<int> to_int(const std::optional<double>& value) {
        if (!value) return std::nullopt;
        return static_cast<int>(*value);
    }

    static OptionQuote parse_quote(const CsvTable& table, const std::vector<std::string>& row) {
        OptionQuote q;
        q.contract = table.text(row, "contract");
        q.date = table.text(row, "date");
        q.underlying = table.text(row, "underlying");
        q.expiration = table.text(row, "expiration");
        assign(q.strike, table.number(row, "strike"), q.missing_fields);
        q.right = table.text(row, "right");
        q.bid = table.number(row, "bid");
        q.ask = table.number(row, "ask");
        q.mid = table.number(row, "mid");
        q.spread = table.number(row, "spread");
        assign(q.volume, table.number(row, "volume"), q.missing_fields);
        q.iv = table.number(row, "iv");
        q.delta = table.number(row, "delta");
        q.gamma = table.number(row, "gamma");
        q.vega = table.number(row, "vega");
        q.theta = table.number(row, "theta");
        q.underlying_price = table.number(row, "underlying_price");
        q.data_quality = table.text(row, "data_quality");
        return q;
    }

    static std::string swarm_path(const std::string& swarm_id, const std::string& suffix) {
        return "/api/polarislink/swarm/" + Query::encode(swarm_id) + suffix;
    }

    static std::optional<double> parse_retry_after(const std::string& value) {
        return CsvTable::parse_number(value);
    }

    [[noreturn]] static void throw_for(const HttpResponse& res) {
        std::string message = extract_json_string(res.body, "message");
        std::string error = extract_json_string(res.body, "error");
        if (!error.empty() && !message.empty() && error != message) message = error + ": " + message;
        if (message.empty()) message = error;
        if (message.empty()) message = "HTTP " + std::to_string(res.status);
        std::string code = extract_json_string(res.body, "code");
        std::string request_id = res.header("x-request-id");
        if (request_id.empty()) request_id = extract_json_string(res.body, "requestId");
        auto retry_after = parse_retry_after(res.header("retry-after"));
        switch (res.status) {
            case 401: throw AuthenticationError(res.status, code, message, request_id, retry_after, res.body);
            case 403: throw PermissionDeniedError(res.status, code, message, request_id, retry_after, res.body);
            case 404: throw NotFoundError(res.status, code, message, request_id, retry_after, res.body);
            case 409: throw ConflictError(res.status, code, message, request_id, retry_after, res.body);
            case 429: throw RateLimitError(res.status, code, message, request_id, retry_after, res.body);
            default: break;
        }
        if (res.status >= 500) throw ServerError(res.status, code, message, request_id, retry_after, res.body);
        throw PolarisLinkError(res.status, code, message, request_id, retry_after, res.body);
    }

    bool state_change(const std::string& method, const std::string& path, const std::string& body) {
        HttpResponse res = send_with_retry(method, path, body, "application/json");
        if (res.ok()) return true;
        if (res.status == 401 || res.status == 429 || res.status >= 500) throw_for(res);
        return false;
    }

    static bool is_idempotent(const std::string& method) {
        return method == "GET" || method == "HEAD" || method == "PUT" || method == "DELETE" || method == "OPTIONS";
    }

    double backoff_seconds(int attempt, std::optional<double> retry_after) const {
        static thread_local std::mt19937 rng{std::random_device{}()};
        double ceiling = std::min(30.0, 0.5 * std::pow(2.0, attempt));
        std::uniform_real_distribution<double> dist(0.0, ceiling);
        double delay = dist(rng);
        if (retry_after) delay = std::max(delay, std::min(*retry_after, 300.0));
        return delay;
    }

    HttpResponse send_with_retry(const std::string& method, const std::string& path, const std::string& body,
                                 const std::string& accept) {
        const bool replay_safe = is_idempotent(method);
        const std::string idempotency_key = (method == "POST" || method == "PATCH") ? random_key() : "";
        for (int attempt = 0;; ++attempt) {
            HttpResponse res;
            try {
                res = http_request(method, path, body, accept, idempotency_key);
            } catch (const TransportError&) {
                if (!replay_safe || attempt >= m_max_retries) throw;
                std::this_thread::sleep_for(std::chrono::duration<double>(backoff_seconds(attempt, std::nullopt)));
                continue;
            }
            bool retryable = res.status == 429 || (replay_safe && (res.status == 502 || res.status == 503 || res.status == 504));
            if (!retryable || attempt >= m_max_retries) return res;
            std::this_thread::sleep_for(std::chrono::duration<double>(backoff_seconds(attempt, parse_retry_after(res.header("retry-after")))));
        }
    }

    static std::string random_key() {
        static thread_local std::mt19937_64 rng{std::random_device{}()};
        std::ostringstream o;
        o << std::hex << std::setfill('0') << std::setw(16) << rng() << std::setw(16) << rng();
        return o.str();
    }

    static void parse_header_line(const std::string& line, HttpResponse& res) {
        if (line.rfind("HTTP/", 0) == 0) {
            res.headers.clear();
            auto sp = line.find(' ');
            if (sp != std::string::npos) res.status = std::strtol(line.c_str() + sp + 1, nullptr, 10);
            return;
        }
        auto colon = line.find(':');
        if (colon == std::string::npos) return;
        std::string key = line.substr(0, colon);
        std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
        std::string value = line.substr(colon + 1);
        while (!value.empty() && std::isspace(static_cast<unsigned char>(value.front()))) value.erase(value.begin());
        while (!value.empty() && std::isspace(static_cast<unsigned char>(value.back()))) value.pop_back();
        res.headers[key] = value;
    }

#if defined(POLARISLINK_HAS_LIBCURL)
    static size_t curl_body_cb(void* contents, size_t size, size_t nmemb, void* userp) {
        static_cast<std::string*>(userp)->append(static_cast<char*>(contents), size * nmemb);
        return size * nmemb;
    }

    static size_t curl_header_cb(char* buffer, size_t size, size_t nitems, void* userp) {
        std::string line(buffer, size * nitems);
        while (!line.empty() && (line.back() == '\r' || line.back() == '\n')) line.pop_back();
        if (!line.empty()) parse_header_line(line, *static_cast<HttpResponse*>(userp));
        return size * nitems;
    }
#endif

    static std::string escape_curl_config_value(const std::string& val) {
        std::ostringstream o;
        for (char c : val) {
            if (c == '"') o << "\\\"";
            else if (c == '\\') o << "\\\\";
            else if (c == '\n') o << "\\n";
            else if (c == '\r') o << "\\r";
            else if (c == '\t') o << "\\t";
            else o << c;
        }
        return o.str();
    }

    HttpResponse http_request(const std::string& method, const std::string& path, const std::string& body,
                              const std::string& accept, const std::string& idempotency_key) {
        const std::string url = m_base_url + path;
        HttpResponse res;
#if defined(POLARISLINK_HAS_LIBCURL)
        CURL* curl = curl_easy_init();
        if (!curl) throw TransportError("libcurl initialization failed");
        struct curl_slist* headers = nullptr;
        headers = curl_slist_append(headers, (std::string("User-Agent: ") + POLARISLINK_USER_AGENT).c_str());
        headers = curl_slist_append(headers, ("Accept: " + accept).c_str());
        if (!m_api_key.empty()) headers = curl_slist_append(headers, ("Authorization: Bearer " + m_api_key).c_str());
        if (!idempotency_key.empty()) headers = curl_slist_append(headers, ("Idempotency-Key: " + idempotency_key).c_str());
        if (!body.empty()) {
            headers = curl_slist_append(headers, "Content-Type: application/json");
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
            curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
        }
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_body_cb);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res.body);
        curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_header_cb);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &res);
        curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, m_timeout_seconds);
        CURLcode rc = curl_easy_perform(curl);
        long status = 0;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
        if (rc != CURLE_OK) throw TransportError(std::string("libcurl request failed: ") + curl_easy_strerror(rc));
        res.status = status;
        return res;
#else
        char cfg_path[] = "/tmp/polarislink_cfg_XXXXXX";
        char hdr_path[] = "/tmp/polarislink_hdr_XXXXXX";
        char out_path[] = "/tmp/polarislink_out_XXXXXX";
        int cfg_fd = mkstemp(cfg_path);
        int hdr_fd = mkstemp(hdr_path);
        int out_fd = mkstemp(out_path);
        auto cleanup = [&]() {
            if (cfg_fd >= 0) unlink(cfg_path);
            if (hdr_fd >= 0) unlink(hdr_path);
            if (out_fd >= 0) unlink(out_path);
        };
        if (cfg_fd < 0 || hdr_fd < 0 || out_fd < 0) {
            if (cfg_fd >= 0) close(cfg_fd);
            if (hdr_fd >= 0) close(hdr_fd);
            if (out_fd >= 0) close(out_fd);
            cleanup();
            throw TransportError("failed to allocate private curl config files");
        }
        fchmod(cfg_fd, 0600);
        close(hdr_fd);
        close(out_fd);
        std::ostringstream cfg;
        cfg << "url = \"" << escape_curl_config_value(url) << "\"\n";
        cfg << "request = \"" << escape_curl_config_value(method) << "\"\n";
        cfg << "header = \"User-Agent: " << POLARISLINK_USER_AGENT << "\"\n";
        cfg << "header = \"Accept: " << escape_curl_config_value(accept) << "\"\n";
        if (!m_api_key.empty()) cfg << "header = \"Authorization: Bearer " << escape_curl_config_value(m_api_key) << "\"\n";
        if (!idempotency_key.empty()) cfg << "header = \"Idempotency-Key: " << idempotency_key << "\"\n";
        if (!body.empty()) {
            cfg << "header = \"Content-Type: application/json\"\n";
            cfg << "data-binary = \"" << escape_curl_config_value(body) << "\"\n";
        }
        cfg << "compressed\n";
        cfg << "location\n";
        cfg << "max-time = " << m_timeout_seconds << "\n";
        cfg << "dump-header = \"" << hdr_path << "\"\n";
        cfg << "output = \"" << out_path << "\"\n";
        const std::string cfg_data = cfg.str();
        ssize_t written = write(cfg_fd, cfg_data.data(), cfg_data.size());
        close(cfg_fd);
        if (written < static_cast<ssize_t>(cfg_data.size())) {
            cleanup();
            throw TransportError("failed to write curl config");
        }
        char arg0[] = "curl";
        char arg1[] = "-sS";
        char arg2[] = "-K";
        char* argv[] = {arg0, arg1, arg2, cfg_path, nullptr};
#if defined(__APPLE__)
        char** envp = *_NSGetEnviron();
#else
        char** envp = environ;
#endif
        pid_t pid = 0;
        if (posix_spawnp(&pid, "curl", nullptr, nullptr, argv, envp) != 0) {
            cleanup();
            throw TransportError("failed to spawn curl");
        }
        int wstatus = 0;
        if (waitpid(pid, &wstatus, 0) < 0 || !WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
            int code = WIFEXITED(wstatus) ? WEXITSTATUS(wstatus) : -1;
            cleanup();
            throw TransportError("curl transport failed with exit code " + std::to_string(code));
        }
        std::ifstream hdr_stream(hdr_path, std::ios::binary);
        std::string line;
        while (std::getline(hdr_stream, line)) {
            while (!line.empty() && (line.back() == '\r' || line.back() == '\n')) line.pop_back();
            if (!line.empty()) parse_header_line(line, res);
        }
        std::ifstream out_stream(out_path, std::ios::binary);
        std::ostringstream body_buf;
        body_buf << out_stream.rdbuf();
        res.body = body_buf.str();
        cleanup();
        if (res.status == 0) throw TransportError("curl returned no HTTP status");
        return res;
#endif
    }
};

}
