#pragma once
#include "uefi.h"
#include "crypto.h"

/* TLS 1.2 record types */
#define TLS_CONTENT_CHANGE_CIPHER_SPEC 20
#define TLS_CONTENT_ALERT             21
#define TLS_CONTENT_HANDSHAKE         22
#define TLS_CONTENT_APPLICATION_DATA  23

/* TLS 1.2 handshake types */
#define TLS_HS_CLIENT_HELLO    1
#define TLS_HS_SERVER_HELLO    2
#define TLS_HS_CERTIFICATE     11
#define TLS_HS_SERVER_KEY_EXCHANGE 12
#define TLS_HS_SERVER_HELLO_DONE 14
#define TLS_HS_CLIENT_KEY_EXCHANGE 16
#define TLS_HS_FINISHED        20

/* TLS cipher suites */
#define TLS_CS_ECDHE_ECDSA_AES128_GCM_SHA256 0xC02B
#define TLS_CS_ECDHE_RSA_AES128_GCM_SHA256   0xC02F

/* TLS alerts */
#define TLS_ALERT_LEVEL_WARNING 1
#define TLS_ALERT_LEVEL_FATAL   2

/* Maximum record size */
#define TLS_RECORD_SIZE 16408

/* TLS context */
struct tls_ctx {
    /* Connection state */
    int      state;
    uint16_t cipher_suite;

    /* Key material (after handshake) */
    uint8_t  client_write_key[16];
    uint8_t  server_write_key[16];
    uint8_t  client_write_iv[4];
    uint8_t  server_write_iv[4];

    /* Sequence numbers */
    uint64_t client_seq;
    uint64_t server_seq;

    /* Handshake hash context */
    uint8_t  hs_hash[SHA256_CTX_SIZE];

    /* Handshake messages buffer (for verify_data) */
    uint8_t  hs_messages[4096];
    uint32_t hs_messages_len;

    /* Server random + client random */
    uint8_t  client_random[32];
    uint8_t  server_random[32];

    /* Master secret */
    uint8_t  master_secret[48];

    /* ECDHE ephemeral key */
    uint8_t  ecdhe_privkey[32];
    uint8_t  ecdhe_pubkey[64];

    /* CCS state */
    int      send_ccs;  /* we sent CCS - encrypt outgoing */
    int      recv_ccs;  /* we received CCS - decrypt incoming */

    /* Raw TCP state for TLS */
    uint8_t  *record_buf;
    uint32_t record_buf_len;
};

/* Initialize TLS context */
void tls_init(struct tls_ctx *ctx);

/* Perform TLS handshake and connect */
int tls_connect(const uint8_t *ip, uint16_t port, const char *hostname,
                struct tls_ctx *ctx);

/* Send application data (encrypted) */
int tls_send(struct tls_ctx *ctx, const void *data, uint32_t len);

/* Receive application data (decrypted) */
int tls_recv(struct tls_ctx *ctx, void *buf, uint32_t max_len, uint32_t timeout_ms);

/* Close TLS connection */
void tls_close(struct tls_ctx *ctx);

/* HTTP over TLS helper */
int https_get(const char *host, const char *path, char *body, uint32_t max_body);
