#ifndef _WIN32
#define _DARWIN_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif

#include "../include/r_client_runtime.h"
#include "../include/r_client_steering.h"

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
#include <windows.h>
#include <windns.h>
#include <ws2tcpip.h>

#include "r_win32_udp.h"
#else
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <fcntl.h>
#include <netdb.h>
#include <resolv.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>
#endif

enum {
    R_RUNTIME_MAX_SRV_RECORDS = 32,
    R_RUNTIME_DNS_PACKET_SIZE = 65536,
};

static const char R_RUNTIME_FIXED_TARGET[] =
    "s-1.ratelimitly-example.invalid";

const char *r_runtime_status_name(int status) {
    switch (status) {
        case RCLIENT_OK:
            return "ok";
        case RCLIENT_ERR_IO:
            return "I/O error";
        case RCLIENT_ERR_TIMEOUT:
            return "timeout";
        case RCLIENT_ERR_PROTOCOL:
            return "protocol error";
        case RCLIENT_ERR_AUTH:
            return "authentication error";
        case RCLIENT_ERR_DNS:
            return "DNS error";
        case RCLIENT_ERR_CONFIG:
            return "configuration error";
        case RCLIENT_ERR_NOMEM:
            return "out of memory";
        default:
            return "unknown error";
    }
}

uint64_t r_runtime_wall_time_ms(void) {
#ifdef _WIN32
    FILETIME file_time;
    GetSystemTimeAsFileTime(&file_time);
    ULARGE_INTEGER ticks = {
        .LowPart = file_time.dwLowDateTime,
        .HighPart = file_time.dwHighDateTime,
    };
    const uint64_t windows_to_unix_epoch_ms = 11644473600000ULL;
    return ticks.QuadPart / 10000ULL - windows_to_unix_epoch_ms;
#else
    struct timespec now;
    if (clock_gettime(CLOCK_REALTIME, &now) != 0) {
        return 0u;
    }
    return (uint64_t)now.tv_sec * 1000u
        + (uint64_t)now.tv_nsec / 1000000u;
#endif
}

static uint64_t runtime_wall_time(void *context) {
    (void)context;
    return r_runtime_wall_time_ms();
}

int r_runtime_monotonic_time_ms(uint64_t *out_milliseconds) {
    if (!out_milliseconds) {
        return RCLIENT_ERR_CONFIG;
    }
#ifdef _WIN32
    *out_milliseconds = GetTickCount64();
#else
    struct timespec now;
    if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) {
        return RCLIENT_ERR_IO;
    }
    *out_milliseconds = (uint64_t)now.tv_sec * 1000u
        + (uint64_t)now.tv_nsec / 1000000u;
#endif
    return RCLIENT_OK;
}

static void runtime_log(void *context, r_log_level_t level, const char *message) {
    (void)context;
    static const char *names[] = {"error", "warn", "info", "debug"};
    const char *name = level >= R_LOG_ERROR && level <= R_LOG_DEBUG
        ? names[level]
        : "unknown";
    fprintf(stderr, "rl-c-client[%s]: %s\n", name, message ? message : "");
}

static void runtime_request_profile(
    void *context,
    const r_request_profile_t *profile
) {
    const r_runtime_client_t *runtime = context;
    if (!runtime || !profile) {
        return;
    }
    const char *phase = profile->phase == R_REQUEST_COMPLETION_FINAL_RECEIVE
        ? "final"
        : "round";
    fprintf(
        stderr,
        "rl-c-client[profile]: wait_ms=%llu unit_ms=%llu "
        "replay_count=%lu round=%lu phase=%s status=%d response=%s\n",
        (unsigned long long)profile->wait_ms,
        (unsigned long long)runtime->request_unit_ms,
        (unsigned long)runtime->request_replay_count,
        (unsigned long)profile->round,
        phase,
        profile->status,
        profile->response_selected ? "selected" : "none"
    );
}

static void close_socket(r_runtime_socket_t socket_value) {
#ifdef _WIN32
    closesocket(socket_value);
#else
    close(socket_value);
#endif
}

static int socket_last_error(void) {
#ifdef _WIN32
    return WSAGetLastError();
#else
    return errno;
#endif
}

static bool socket_error_is_address_in_use(int error) {
#ifdef _WIN32
    return error == WSAEADDRINUSE || error == WSAEACCES;
#else
    return error == EADDRINUSE;
#endif
}

static int set_nonblocking(r_runtime_socket_t socket_value) {
#ifdef _WIN32
    u_long enabled = 1u;
    return ioctlsocket(socket_value, FIONBIO, &enabled) == 0 ? 0 : -1;
#else
    int flags = fcntl(socket_value, F_GETFL, 0);
    if (flags < 0 || fcntl(socket_value, F_SETFL, flags | O_NONBLOCK) != 0) {
        return -1;
    }
    return 0;
#endif
}

static r_runtime_socket_t open_udp_socket(
    int family,
    uint16_t port,
    int *out_error
) {
    if (out_error) {
        *out_error = 0;
    }
    r_runtime_socket_t socket_value = socket(family, SOCK_DGRAM, IPPROTO_UDP);
    if (socket_value == R_RUNTIME_INVALID_SOCKET) {
        if (out_error) {
            *out_error = socket_last_error();
        }
        return R_RUNTIME_INVALID_SOCKET;
    }
#ifdef _WIN32
    r_win32_udp_disable_connreset(socket_value);
    int exclusive = 1;
    if (setsockopt(
            socket_value,
            SOL_SOCKET,
            SO_EXCLUSIVEADDRUSE,
            (const char *)&exclusive,
            (int)sizeof(exclusive)
        ) != 0) {
        if (out_error) {
            *out_error = socket_last_error();
        }
        close_socket(socket_value);
        return R_RUNTIME_INVALID_SOCKET;
    }
#endif
    if (set_nonblocking(socket_value) != 0) {
        if (out_error) {
            *out_error = socket_last_error();
        }
        close_socket(socket_value);
        return R_RUNTIME_INVALID_SOCKET;
    }

    if (family == AF_INET) {
        struct sockaddr_in address = {0};
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = htonl(INADDR_ANY);
        address.sin_port = htons(port);
        if (bind(socket_value, (const struct sockaddr *)&address,
                (r_socklen_t)sizeof(address)) != 0) {
            if (out_error) {
                *out_error = socket_last_error();
            }
            close_socket(socket_value);
            return R_RUNTIME_INVALID_SOCKET;
        }
    } else {
        struct sockaddr_in6 address = {0};
        address.sin6_family = AF_INET6;
        address.sin6_addr = in6addr_any;
        address.sin6_port = htons(port);
        int ipv6_only = 1;
#ifdef _WIN32
        (void)setsockopt(socket_value, IPPROTO_IPV6, IPV6_V6ONLY,
            (const char *)&ipv6_only, (int)sizeof(ipv6_only));
#else
        (void)setsockopt(socket_value, IPPROTO_IPV6, IPV6_V6ONLY,
            &ipv6_only, (socklen_t)sizeof(ipv6_only));
#endif
        if (bind(socket_value, (const struct sockaddr *)&address,
                (r_socklen_t)sizeof(address)) != 0) {
            if (out_error) {
                *out_error = socket_last_error();
            }
            close_socket(socket_value);
            return R_RUNTIME_INVALID_SOCKET;
        }
    }
    return socket_value;
}

typedef struct runtime_steering_bind {
    int family;
    r_runtime_socket_t socket_value;
} runtime_steering_bind_t;

static r_steering_bind_result_t runtime_try_steering_port(
    void *user,
    uint16_t port
) {
    runtime_steering_bind_t *binding = user;
    int error = 0;
    binding->socket_value = open_udp_socket(binding->family, port, &error);
    if (binding->socket_value != R_RUNTIME_INVALID_SOCKET) {
        return R_STEERING_BIND_OK;
    }
    return socket_error_is_address_in_use(error)
        ? R_STEERING_BIND_OCCUPIED
        : R_STEERING_BIND_ERROR;
}

static int runtime_socket_family_and_port(
    r_runtime_socket_t socket_value,
    int *out_family,
    uint16_t *out_port
) {
    struct sockaddr_storage address;
    memset(&address, 0, sizeof(address));
    r_socklen_t address_length = (r_socklen_t)sizeof(address);
    if (getsockname(
            socket_value,
            (struct sockaddr *)&address,
            &address_length
        ) != 0) {
        return RCLIENT_ERR_IO;
    }
    if (address.ss_family == AF_INET) {
        *out_family = AF_INET;
        *out_port = ntohs(((struct sockaddr_in *)&address)->sin_port);
        return RCLIENT_OK;
    }
    if (address.ss_family == AF_INET6) {
        *out_family = AF_INET6;
        *out_port = ntohs(((struct sockaddr_in6 *)&address)->sin6_port);
        return RCLIENT_OK;
    }
    return RCLIENT_ERR_IO;
}

static void runtime_on_steering_feedback(void *context, bool keep_port) {
    r_runtime_client_t *runtime = context;
    if (!runtime || keep_port || runtime->socket_count == 0u) {
        return;
    }

    r_runtime_socket_t replacements[2] = {
        R_RUNTIME_INVALID_SOCKET,
        R_RUNTIME_INVALID_SOCKET,
    };
    for (size_t i = 0u; i < runtime->socket_count; i++) {
        int family = 0;
        uint16_t current_port = 0u;
        if (runtime_socket_family_and_port(
                runtime->sockets[i],
                &family,
                &current_port
            ) != RCLIENT_OK) {
            goto fail;
        }
        uint16_t first_port = r_client_next_steering_port(current_port);
        runtime_steering_bind_t binding = {
            .family = family,
            .socket_value = R_RUNTIME_INVALID_SOCKET,
        };
        uint16_t selected_port = 0u;
        uint16_t following_port = 0u;
        if (r_client_select_steering_port(
                first_port,
                runtime_try_steering_port,
                &binding,
                &selected_port,
                &following_port
            ) != RCLIENT_OK) {
            goto fail;
        }
        (void)selected_port;
        (void)following_port;
        replacements[i] = binding.socket_value;
    }

    for (size_t i = 0u; i < runtime->socket_count; i++) {
        r_runtime_socket_t previous = runtime->sockets[i];
        runtime->sockets[i] = replacements[i];
        close_socket(previous);
    }
    return;

fail:
    for (size_t i = 0u; i < runtime->socket_count; i++) {
        if (replacements[i] != R_RUNTIME_INVALID_SOCKET) {
            close_socket(replacements[i]);
        }
    }
    runtime_log(runtime, R_LOG_WARN,
        "source-port steering could not acquire replacement sockets");
}

static int runtime_udp_send(
    void *context,
    const r_addr_t *to,
    const uint8_t *buffer,
    size_t length
) {
    r_runtime_client_t *runtime = context;
    if (!runtime || !to || !buffer || length == 0u) {
        return -1;
    }

    r_runtime_socket_t socket_value = R_RUNTIME_INVALID_SOCKET;
    for (size_t i = 0; i < runtime->socket_count; i++) {
        struct sockaddr_storage local;
        r_socklen_t local_length = (r_socklen_t)sizeof(local);
        if (getsockname(runtime->sockets[i], (struct sockaddr *)&local,
                &local_length) == 0
            && local.ss_family == to->sa.ss_family) {
            socket_value = runtime->sockets[i];
            break;
        }
    }
    if (socket_value == R_RUNTIME_INVALID_SOCKET) {
        return -1;
    }

#ifdef _WIN32
    if (length > INT_MAX) {
        return -1;
    }
    int sent = r_win32_udp_sendto(
        socket_value,
        (const char *)buffer,
        (int)length,
        (const struct sockaddr *)&to->sa,
        to->len
    );
    return sent == (int)length ? 0 : -1;
#else
    ssize_t sent;
    do {
        sent = sendto(socket_value, buffer, length, 0,
            (const struct sockaddr *)&to->sa, to->len);
    } while (sent < 0 && errno == EINTR);
    return sent == (ssize_t)length ? 0 : -1;
#endif
}

static int copy_fixed_host(
    r_runtime_client_t *runtime,
    const r_runtime_options_t *options
) {
    if (!options->server_host && options->server_port == 0u) {
        return RCLIENT_OK;
    }
    if (!options->server_host || options->server_port == 0u) {
        return RCLIENT_ERR_CONFIG;
    }
    size_t length = strlen(options->server_host);
    if (length == 0u || length >= sizeof(runtime->server_host)) {
        return RCLIENT_ERR_CONFIG;
    }
    memcpy(runtime->server_host, options->server_host, length + 1u);
    runtime->server_port = options->server_port;
    return RCLIENT_OK;
}

static int resolve_addresses(
    const char *host,
    r_dns_addr_cb callback,
    void *user
) {
    struct addrinfo hints = {0};
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;

    struct addrinfo *addresses = NULL;
    if (getaddrinfo(host, NULL, &hints, &addresses) != 0) {
        callback(user, RCLIENT_ERR_DNS, NULL, 0u);
        return 0;
    }

    size_t count = 0u;
    for (const struct addrinfo *item = addresses; item; item = item->ai_next) {
        if ((item->ai_family == AF_INET || item->ai_family == AF_INET6)
            && (size_t)item->ai_addrlen <= sizeof(struct sockaddr_storage)) {
            count++;
        }
    }
    r_addr_t *result = count ? calloc(count, sizeof(*result)) : NULL;
    if (count && !result) {
        freeaddrinfo(addresses);
        callback(user, RCLIENT_ERR_NOMEM, NULL, 0u);
        return 0;
    }

    size_t index = 0u;
    for (const struct addrinfo *item = addresses; item; item = item->ai_next) {
        if ((item->ai_family != AF_INET && item->ai_family != AF_INET6)
            || (size_t)item->ai_addrlen > sizeof(struct sockaddr_storage)) {
            continue;
        }
        memcpy(&result[index].sa, item->ai_addr, (size_t)item->ai_addrlen);
        result[index].len = (r_socklen_t)item->ai_addrlen;
        index++;
    }
    freeaddrinfo(addresses);
    callback(user, count ? RCLIENT_OK : RCLIENT_ERR_DNS, result, count);
    free(result);
    return 0;
}

static int runtime_resolve_addresses(
    void *context,
    const char *name,
    r_dns_req_id_t *request_id,
    r_dns_addr_cb callback,
    void *user
) {
    r_runtime_client_t *runtime = context;
    if (!runtime || !name || !request_id || !callback) {
        return -1;
    }
    *request_id = 0u;
    const char *host = runtime->server_host[0] != '\0'
        && strcmp(name, R_RUNTIME_FIXED_TARGET) == 0
        ? runtime->server_host
        : name;
    return resolve_addresses(host, callback, user);
}

#ifdef _WIN32
static int resolve_srv_records(
    const char *name,
    r_dns_srv_cb callback,
    void *user
) {
    PDNS_RECORD records = NULL;
    DNS_STATUS query_status = DnsQuery_A(
        name,
        DNS_TYPE_SRV,
        DNS_QUERY_STANDARD,
        NULL,
        &records,
        NULL
    );
    if (query_status != ERROR_SUCCESS) {
        callback(user, RCLIENT_ERR_DNS, NULL, 0u);
        return 0;
    }

    r_srv_record_t result[R_RUNTIME_MAX_SRV_RECORDS];
    size_t count = 0u;
    for (PDNS_RECORD item = records;
         item && count < R_RUNTIME_MAX_SRV_RECORDS;
         item = item->pNext) {
        if (item->wType != DNS_TYPE_SRV || !item->Data.SRV.pNameTarget) {
            continue;
        }
        result[count].target = item->Data.SRV.pNameTarget;
        result[count].port = item->Data.SRV.wPort;
        result[count].priority = item->Data.SRV.wPriority;
        result[count].weight = item->Data.SRV.wWeight;
        uint64_t ttl_ms = (uint64_t)item->dwTtl * 1000u;
        result[count].ttl_ms = ttl_ms > UINT32_MAX
            ? UINT32_MAX
            : (uint32_t)ttl_ms;
        count++;
    }
    callback(user, count ? RCLIENT_OK : RCLIENT_ERR_DNS, result, count);
    DnsRecordListFree(records, DnsFreeRecordList);
    return 0;
}
#else
static int resolve_srv_records(
    const char *name,
    r_dns_srv_cb callback,
    void *user
) {
    unsigned char *answer = malloc(R_RUNTIME_DNS_PACKET_SIZE);
    if (!answer) {
        callback(user, RCLIENT_ERR_NOMEM, NULL, 0u);
        return 0;
    }
    int answer_length = res_query(
        name,
        ns_c_in,
        ns_t_srv,
        answer,
        R_RUNTIME_DNS_PACKET_SIZE
    );
    ns_msg message;
    if (answer_length < 0 || ns_initparse(answer, answer_length, &message) != 0) {
        free(answer);
        callback(user, RCLIENT_ERR_DNS, NULL, 0u);
        return 0;
    }

    int answer_count = ns_msg_count(message, ns_s_an);
    if (answer_count > R_RUNTIME_MAX_SRV_RECORDS) {
        answer_count = R_RUNTIME_MAX_SRV_RECORDS;
    }
    r_srv_record_t records[R_RUNTIME_MAX_SRV_RECORDS];
    char targets[R_RUNTIME_MAX_SRV_RECORDS][NS_MAXDNAME];
    size_t count = 0u;
    for (int i = 0; i < answer_count; i++) {
        ns_rr record;
        if (ns_parserr(&message, ns_s_an, i, &record) != 0
            || ns_rr_type(record) != ns_t_srv
            || ns_rr_rdlen(record) < 7) {
            continue;
        }
        const unsigned char *data = ns_rr_rdata(record);
        if (dn_expand(answer, answer + answer_length, data + 6,
                targets[count], sizeof(targets[count])) < 0) {
            continue;
        }
        uint64_t ttl_ms = (uint64_t)ns_rr_ttl(record) * 1000u;
        records[count].target = targets[count];
        records[count].priority = ns_get16(data);
        records[count].weight = ns_get16(data + 2);
        records[count].port = ns_get16(data + 4);
        records[count].ttl_ms = ttl_ms > UINT32_MAX
            ? UINT32_MAX
            : (uint32_t)ttl_ms;
        count++;
    }
    callback(user, count ? RCLIENT_OK : RCLIENT_ERR_DNS, records, count);
    free(answer);
    return 0;
}
#endif

static int runtime_resolve_srv(
    void *context,
    const char *name,
    r_dns_req_id_t *request_id,
    r_dns_srv_cb callback,
    void *user
) {
    r_runtime_client_t *runtime = context;
    if (!runtime || !name || !request_id || !callback) {
        return -1;
    }
    *request_id = 0u;
    if (runtime->server_host[0] != '\0') {
        r_srv_record_t record = {
            .target = R_RUNTIME_FIXED_TARGET,
            .port = runtime->server_port,
            .ttl_ms = 60000u,
        };
        callback(user, RCLIENT_OK, &record, 1u);
        return 0;
    }
    return resolve_srv_records(name, callback, user);
}

static void runtime_cancel_dns(void *context, r_dns_req_id_t request_id) {
    (void)context;
    (void)request_id;
}

static const char *runtime_environment_value(const char *name) {
    /*
     * r_runtime_options_t borrows environment strings; it does not own memory
     * that callers must release. Microsoft's _dupenv_s would change that
     * contract by allocating each value. Keep the standard C getenv behavior
     * and suppress only MSVC's non-standard deprecation at this call site.
     */
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4996)
#endif
    const char *value = getenv(name);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
    return value;
}

static int runtime_parse_u64(
    const char *text,
    uint64_t maximum,
    uint64_t *out_value
) {
    if (!text || text[0] == '\0' || !out_value) {
        return RCLIENT_ERR_CONFIG;
    }
    uint64_t parsed = 0u;
    for (const char *cursor = text; *cursor != '\0'; cursor++) {
        if (*cursor < '0' || *cursor > '9') {
            return RCLIENT_ERR_CONFIG;
        }
        uint64_t digit = (uint64_t)(*cursor - '0');
        if (parsed > maximum / 10u
            || (parsed == maximum / 10u && digit > maximum % 10u)) {
            return RCLIENT_ERR_CONFIG;
        }
        parsed = parsed * 10u + digit;
    }
    *out_value = parsed;
    return RCLIENT_OK;
}

int r_runtime_options_from_env(r_runtime_options_t *out_options) {
    if (!out_options) {
        return RCLIENT_ERR_CONFIG;
    }
    memset(out_options, 0, sizeof(*out_options));
    const char *tenant_dns_name = runtime_environment_value(
        "RATELIMITLY_TENANT"
    );
    out_options->tenant_dns_name = tenant_dns_name && tenant_dns_name[0] != '\0'
        ? tenant_dns_name
        : NULL;
    out_options->auth_key = runtime_environment_value(
        "RATELIMITLY_AUTH_KEY"
    );
    out_options->server_host = runtime_environment_value(
        "RATELIMITLY_EXAMPLE_SERVER_HOST"
    );
    const char *unit_text = runtime_environment_value(
        "RATELIMITLY_REQUEST_UNIT_MS"
    );
    const char *replay_text = runtime_environment_value(
        "RATELIMITLY_REQUEST_REPLAY_COUNT"
    );
    if ((unit_text && unit_text[0] != '\0')
        || (replay_text && replay_text[0] != '\0')) {
        r_client_default_request_policy(&out_options->request_policy);
        if (unit_text && unit_text[0] != '\0') {
            uint64_t unit_ms = 0u;
            if (runtime_parse_u64(unit_text, UINT64_MAX, &unit_ms)
                    != RCLIENT_OK
                || unit_ms == 0u) {
                return RCLIENT_ERR_CONFIG;
            }
            out_options->request_policy.unit_ms = unit_ms;
        }
        if (replay_text && replay_text[0] != '\0') {
            uint64_t replay_count = 0u;
            if (runtime_parse_u64(
                    replay_text,
                    R_CLIENT_HA_MAX_REPLAY_COUNT,
                    &replay_count
                ) != RCLIENT_OK) {
                return RCLIENT_ERR_CONFIG;
            }
            out_options->request_policy.replay_count =
                (uint32_t)replay_count;
        }
        out_options->has_request_policy = true;
    }
    const char *profile_text = runtime_environment_value(
        "RATELIMITLY_REQUEST_PROFILE"
    );
    if (profile_text && profile_text[0] != '\0') {
        if (strcmp(profile_text, "1") != 0) {
            return RCLIENT_ERR_CONFIG;
        }
        out_options->profile_requests = true;
    }
    const char *port_text = runtime_environment_value(
        "RATELIMITLY_EXAMPLE_SERVER_PORT"
    );
    if (port_text && port_text[0] != '\0') {
        char *end = NULL;
        errno = 0;
        unsigned long port = strtoul(port_text, &end, 10);
        if (errno != 0 || !end || *end != '\0' || port == 0u
            || port > UINT16_MAX) {
            return RCLIENT_ERR_CONFIG;
        }
        out_options->server_port = (uint16_t)port;
    }
    if (!out_options->auth_key || out_options->auth_key[0] == '\0') {
        return RCLIENT_ERR_CONFIG;
    }
    return (out_options->server_host == NULL)
            == (out_options->server_port == 0u)
        ? RCLIENT_OK
        : RCLIENT_ERR_CONFIG;
}

int r_runtime_client_init(
    r_runtime_client_t *runtime,
    const r_runtime_options_t *options
) {
    if (!runtime || !options || !options->auth_key
            || options->auth_key[0] == '\0') {
        return RCLIENT_ERR_CONFIG;
    }
    memset(runtime, 0, sizeof(*runtime));
    runtime->sockets[0] = R_RUNTIME_INVALID_SOCKET;
    runtime->sockets[1] = R_RUNTIME_INVALID_SOCKET;

#ifdef _WIN32
    WSADATA winsock_data;
    if (WSAStartup(MAKEWORD(2, 2), &winsock_data) != 0) {
        return RCLIENT_ERR_IO;
    }
    runtime->network_started = true;
#endif

    int status = copy_fixed_host(runtime, options);
    if (status != RCLIENT_OK) {
        r_runtime_client_destroy(runtime);
        return status;
    }

    r_runtime_socket_t ipv4 = open_udp_socket(AF_INET, 0u, NULL);
    if (ipv4 != R_RUNTIME_INVALID_SOCKET) {
        runtime->sockets[runtime->socket_count++] = ipv4;
    }
    r_runtime_socket_t ipv6 = open_udp_socket(AF_INET6, 0u, NULL);
    if (ipv6 != R_RUNTIME_INVALID_SOCKET) {
        runtime->sockets[runtime->socket_count++] = ipv6;
    }
    if (runtime->socket_count == 0u) {
        r_runtime_client_destroy(runtime);
        return RCLIENT_ERR_IO;
    }

    r_request_policy_t policy;
    r_client_default_request_policy(&policy);
    if (options->has_request_policy) {
        policy = options->request_policy;
    }
    runtime->request_unit_ms = policy.unit_ms;
    runtime->request_replay_count = policy.replay_count;

    r_client_config_t config = {0};
    config.tenant.dns_name = options->tenant_dns_name;
    config.tenant.auth.secret = options->auth_key;
    config.request_policy = &policy;
    if (options->profile_requests) {
        config.request_profile_cb = runtime_request_profile;
        config.request_profile_user = runtime;
    }

    r_io_ops_t io = {
        .ctx = runtime,
        .udp_send = runtime_udp_send,
        .now_ms = runtime_wall_time,
        .log = runtime_log,
        .on_steering_feedback = runtime_on_steering_feedback,
    };
    r_resolver_ops_t resolver = {
        .ctx = runtime,
        .resolve_srv = runtime_resolve_srv,
        .resolve_addrs = runtime_resolve_addresses,
        .cancel = runtime_cancel_dns,
    };
    status = r_client_create(&config, &io, &resolver, &runtime->handle);
    if (status != RCLIENT_OK) {
        r_runtime_client_destroy(runtime);
    }
    return status;
}

void r_runtime_client_destroy(r_runtime_client_t *runtime) {
    if (!runtime) {
        return;
    }
    if (runtime->handle) {
        r_client_destroy(runtime->handle);
        runtime->handle = NULL;
    }
    for (size_t i = 0; i < runtime->socket_count; i++) {
        if (runtime->sockets[i] != R_RUNTIME_INVALID_SOCKET) {
            close_socket(runtime->sockets[i]);
            runtime->sockets[i] = R_RUNTIME_INVALID_SOCKET;
        }
    }
    runtime->socket_count = 0u;
#ifdef _WIN32
    if (runtime->network_started) {
        WSACleanup();
        runtime->network_started = false;
    }
#endif
}

size_t r_runtime_socket_count(const r_runtime_client_t *runtime) {
    return runtime ? runtime->socket_count : 0u;
}

r_runtime_socket_t r_runtime_socket_at(
    const r_runtime_client_t *runtime,
    size_t index
) {
    return runtime && index < runtime->socket_count
        ? runtime->sockets[index]
        : R_RUNTIME_INVALID_SOCKET;
}

int r_runtime_client_on_readable(
    r_runtime_client_t *runtime,
    r_runtime_socket_t socket_value
) {
    if (!runtime || !runtime->handle
        || socket_value == R_RUNTIME_INVALID_SOCKET) {
        return RCLIENT_ERR_CONFIG;
    }

    for (;;) {
        uint8_t buffer[65536];
        r_addr_t from = {0};
        from.len = (r_socklen_t)sizeof(from.sa);
#ifdef _WIN32
        int length = recvfrom(
            socket_value,
            (char *)buffer,
            (int)sizeof(buffer),
            0,
            (struct sockaddr *)&from.sa,
            &from.len
        );
        if (length == SOCKET_ERROR) {
            int error = WSAGetLastError();
            if (error == WSAEINTR || error == WSAECONNRESET) {
                /*
                 * An alternate Winsock provider may not implement
                 * SIO_UDP_CONNRESET. Consume its asynchronous ICMP report and
                 * keep draining; request deadlines decide server reachability.
                 */
                continue;
            }
            if (error == WSAEWOULDBLOCK) {
                return RCLIENT_OK;
            }
            return RCLIENT_ERR_IO;
        }
#else
        ssize_t length = recvfrom(
            socket_value,
            buffer,
            sizeof(buffer),
            0,
            (struct sockaddr *)&from.sa,
            &from.len
        );
        if (length < 0 && errno == EINTR) {
            continue;
        }
        if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
            return RCLIENT_OK;
        }
        if (length < 0) {
            return RCLIENT_ERR_IO;
        }
#endif
        int status = r_client_on_datagram(
            runtime->handle,
            buffer,
            (size_t)length,
            &from
        );
        if (status == RCLIENT_ERR_PROTOCOL || status == RCLIENT_ERR_AUTH) {
            continue;
        }
        if (status != RCLIENT_OK) {
            return status;
        }
        bool socket_is_current = false;
        for (size_t i = 0u; i < runtime->socket_count; i++) {
            if (runtime->sockets[i] == socket_value) {
                socket_is_current = true;
                break;
            }
        }
        if (!socket_is_current) {
            return RCLIENT_OK;
        }
    }
}

int r_runtime_admission_delay_ms(
    const r_admission_request_t *request,
    uint64_t *out_delay_ms
) {
    if (!out_delay_ms) {
        return RCLIENT_ERR_CONFIG;
    }
    uint64_t deadline_ms = 0u;
    int status = r_client_admission_deadline_ms(request, &deadline_ms);
    if (status != RCLIENT_OK) {
        return status;
    }
    uint64_t now_ms = r_runtime_wall_time_ms();
    *out_delay_ms = deadline_ms > now_ms ? deadline_ms - now_ms : 0u;
    return RCLIENT_OK;
}

int r_runtime_admission_on_timeout(
    r_runtime_client_t *runtime,
    r_admission_request_t *request
) {
    if (!runtime || !runtime->handle) {
        return RCLIENT_ERR_CONFIG;
    }
    return r_client_admission_on_timeout(
        runtime->handle,
        request,
        r_runtime_wall_time_ms()
    );
}

void r_runtime_admission_cancel(
    r_runtime_client_t *runtime,
    r_admission_request_t *request
) {
    if (runtime) {
        r_client_admission_cancel(runtime->handle, request);
    }
}

int r_runtime_admission_run_and_report(
    r_runtime_client_t *runtime,
    r_admission_request_t *request,
    r_runtime_protected_work_cb protected_work,
    void *user,
    uint32_t *out_observed_latency_ms
) {
    if (!runtime || !runtime->handle || !request || !request->admitted
        || request->work_executed
        || !protected_work) {
        return RCLIENT_ERR_CONFIG;
    }

    uint64_t started_ms = 0u;
    int status = r_runtime_monotonic_time_ms(&started_ms);
    if (status != RCLIENT_OK) {
        return status;
    }
    request->work_executed = true;
    status = protected_work(user);
    if (status != RCLIENT_OK) {
        return status;
    }
    uint64_t finished_ms = 0u;
    status = r_runtime_monotonic_time_ms(&finished_ms);
    if (status != RCLIENT_OK || finished_ms < started_ms) {
        return RCLIENT_ERR_IO;
    }

    uint64_t elapsed_ms = finished_ms - started_ms;
    uint32_t observed_ms = elapsed_ms > UINT32_MAX
        ? UINT32_MAX
        : (uint32_t)elapsed_ms;
    if (out_observed_latency_ms) {
        *out_observed_latency_ms = observed_ms;
    }
    return r_client_admission_report_latency(
        runtime->handle,
        request,
        observed_ms
    );
}
