/* Reports the C sizes and alignments of the Mbed TLS context structs so
 * src/platform/tls_server.zig can treat them as opaque and heap-allocate them
 * without mirroring their layout in Zig. */

#include <stddef.h>

#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/net_sockets.h>
#include <mbedtls/pk.h>
#include <mbedtls/ssl.h>
#include <mbedtls/x509_crt.h>

size_t nx_sizeof_ssl_context(void) { return sizeof(mbedtls_ssl_context); }
size_t nx_sizeof_ssl_config(void) { return sizeof(mbedtls_ssl_config); }
size_t nx_sizeof_x509_crt(void) { return sizeof(mbedtls_x509_crt); }
size_t nx_sizeof_pk_context(void) { return sizeof(mbedtls_pk_context); }
size_t nx_sizeof_entropy_context(void) { return sizeof(mbedtls_entropy_context); }
size_t nx_sizeof_ctr_drbg_context(void) { return sizeof(mbedtls_ctr_drbg_context); }

/* The public key of the first certificate in a chain. tls_server.zig keeps
 * mbedtls_x509_crt opaque, so it cannot reach this field on its own. */
mbedtls_pk_context *nx_x509_crt_pk(mbedtls_x509_crt *crt) { return &crt->pk; }

/* Largest alignment any of the above needs. tls_server.zig allocates every
 * context at a fixed comptime alignment and asserts it covers this value. */
size_t nx_max_context_alignment(void)
{
    size_t max = _Alignof(mbedtls_ssl_context);
    if (_Alignof(mbedtls_ssl_config) > max) max = _Alignof(mbedtls_ssl_config);
    if (_Alignof(mbedtls_x509_crt) > max) max = _Alignof(mbedtls_x509_crt);
    if (_Alignof(mbedtls_pk_context) > max) max = _Alignof(mbedtls_pk_context);
    if (_Alignof(mbedtls_entropy_context) > max) max = _Alignof(mbedtls_entropy_context);
    if (_Alignof(mbedtls_ctr_drbg_context) > max) max = _Alignof(mbedtls_ctr_drbg_context);
    return max;
}

/* The configuration enums and error codes tls_server.zig transcribes from the
 * pinned headers. A version bump that renumbers one of these would otherwise
 * change behaviour silently -- a moved close_notify inverts the truncation
 * check -- so the Zig side compares every value against the getter here. */
int nx_const_ssl_transport_stream(void) { return MBEDTLS_SSL_TRANSPORT_STREAM; }
int nx_const_ssl_is_server(void) { return MBEDTLS_SSL_IS_SERVER; }
int nx_const_ssl_verify_none(void) { return MBEDTLS_SSL_VERIFY_NONE; }
int nx_const_ssl_preset_default(void) { return MBEDTLS_SSL_PRESET_DEFAULT; }

int nx_const_err_ssl_conn_eof(void) { return MBEDTLS_ERR_SSL_CONN_EOF; }
int nx_const_err_ssl_peer_close_notify(void) { return MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY; }
int nx_const_err_ssl_want_read(void) { return MBEDTLS_ERR_SSL_WANT_READ; }
int nx_const_err_ssl_want_write(void) { return MBEDTLS_ERR_SSL_WANT_WRITE; }
int nx_const_err_net_recv_failed(void) { return MBEDTLS_ERR_NET_RECV_FAILED; }
int nx_const_err_net_send_failed(void) { return MBEDTLS_ERR_NET_SEND_FAILED; }
