/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef NEQO_GLUE_FFI_GENERATED_H_
#define NEQO_GLUE_FFI_GENERATED_H_

/* Generated with cbindgen:0.29.2 */

/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
 */

namespace mozilla {
namespace net {
class NeqoDecoder;
class NeqoEncoder;
class NeqoHttp3Conn;
union NetAddr;
}  // namespace net
}  // namespace mozilla
 

#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>
#include "certt.h"
#include "prerror.h"
#include "nsString.h"
#include "nsTArray.h"

namespace mozilla {
namespace net {

enum class BrotliDecoderResult {
  Error = 0,
  Success = 1,
  NeedsMoreInput = 2,
  NeedsMoreOutput = 3,
};

enum class WebTransportStreamType {
  BiDi,
  UniDi,
};

struct ProcessInputResult {
  nsresult result;
  uint32_t bytes_read;
};

using SendFunc = nsresult(*)(void *context,
                             uint16_t addr_family,
                             const uint8_t *addr,
                             uint16_t port,
                             const uint8_t *data,
                             uint32_t size);

using SetTimerFunc = void(*)(void *context, uint64_t timeout);

struct ProcessOutputAndSendResult {
  nsresult result;
  uint32_t bytes_written;
};

struct CloseError {
  enum class Tag {
    TransportInternalError,
    TransportInternalErrorOther,
    TransportError,
    CryptoError,
    CryptoAlert,
    PeerAppError,
    PeerError,
    AppError,
    EchRetry,
  };

  struct TransportInternalErrorOther_Body {
    uint16_t _0;
  };

  struct TransportError_Body {
    uint64_t _0;
  };

  struct CryptoError_Body {
    uint64_t _0;
  };

  struct CryptoAlert_Body {
    uint8_t _0;
  };

  struct PeerAppError_Body {
    uint64_t _0;
  };

  struct PeerError_Body {
    uint64_t _0;
  };

  struct AppError_Body {
    uint64_t _0;
  };

  Tag tag;
  union {
    TransportInternalErrorOther_Body transport_internal_error_other;
    TransportError_Body transport_error;
    CryptoError_Body crypto_error;
    CryptoAlert_Body crypto_alert;
    PeerAppError_Body peer_app_error;
    PeerError_Body peer_error;
    AppError_Body app_error;
  };
};

struct SessionCloseReasonExternal {
  enum class Tag {
    Error,
    Status,
    Clean,
  };

  struct Error_Body {
    uint64_t _0;
  };

  struct Status_Body {
    uint16_t _0;
  };

  struct Clean_Body {
    uint32_t _0;
  };

  Tag tag;
  union {
    Error_Body error;
    Status_Body status;
    Clean_Body clean;
  };
};

struct WebTransportEventExternal {
  enum class Tag {
    Negotiated,
    Session,
    SessionClosed,
    NewStream,
    Datagram,
  };

  struct Negotiated_Body {
    bool _0;
  };

  struct Session_Body {
    uint64_t _0;
  };

  struct SessionClosed_Body {
    uint64_t stream_id;
    SessionCloseReasonExternal reason;
  };

  struct NewStream_Body {
    uint64_t stream_id;
    WebTransportStreamType stream_type;
    uint64_t session_id;
  };

  struct Datagram_Body {
    uint64_t session_id;
  };

  Tag tag;
  union {
    Negotiated_Body negotiated;
    Session_Body session;
    SessionClosed_Body session_closed;
    NewStream_Body new_stream;
    Datagram_Body datagram;
  };
};

struct ConnectUdpEventExternal {
  enum class Tag {
    Negotiated,
    Session,
    SessionClosed,
    Datagram,
  };

  struct Negotiated_Body {
    bool _0;
  };

  struct Session_Body {
    uint64_t _0;
  };

  struct SessionClosed_Body {
    uint64_t stream_id;
    SessionCloseReasonExternal reason;
  };

  struct Datagram_Body {
    uint64_t session_id;
  };

  Tag tag;
  union {
    Negotiated_Body negotiated;
    Session_Body session;
    SessionClosed_Body session_closed;
    Datagram_Body datagram;
  };
};

struct Http3Event {
  enum class Tag {
    /// A request stream has space for more data to be sent.
    DataWritable,
    /// A server has sent a `STOP_SENDING` frame.
    StopSending,
    HeaderReady,
    /// New bytes available for reading.
    DataReadable,
    /// Peer reset the stream.
    Reset,
    /// A `PushPromise`
    PushPromise,
    /// A push response headers are ready.
    PushHeaderReady,
    /// New bytes are available on a push stream for reading.
    PushDataReadable,
    /// A push has been canceled.
    PushCanceled,
    PushReset,
    RequestsCreatable,
    AuthenticationNeeded,
    ZeroRttRejected,
    ConnectionConnected,
    GoawayReceived,
    ConnectionClosing,
    ConnectionClosed,
    ResumptionToken,
    EchFallbackAuthenticationNeeded,
    WebTransport,
    ConnectUdp,
    NoEvent,
  };

  struct DataWritable_Body {
    uint64_t stream_id;
  };

  struct StopSending_Body {
    uint64_t stream_id;
    uint64_t error;
  };

  struct HeaderReady_Body {
    uint64_t stream_id;
    bool fin;
    bool interim;
  };

  struct DataReadable_Body {
    uint64_t stream_id;
  };

  struct Reset_Body {
    uint64_t stream_id;
    uint64_t error;
    bool local;
  };

  struct PushPromise_Body {
    uint64_t push_id;
    uint64_t request_stream_id;
  };

  struct PushHeaderReady_Body {
    uint64_t push_id;
    bool fin;
  };

  struct PushDataReadable_Body {
    uint64_t push_id;
  };

  struct PushCanceled_Body {
    uint64_t push_id;
  };

  struct PushReset_Body {
    uint64_t push_id;
    uint64_t error;
  };

  struct ConnectionClosing_Body {
    CloseError error;
  };

  struct ConnectionClosed_Body {
    CloseError error;
  };

  struct ResumptionToken_Body {
    uint64_t expire_in;
  };

  struct WebTransport_Body {
    WebTransportEventExternal _0;
  };

  struct ConnectUdp_Body {
    ConnectUdpEventExternal _0;
  };

  Tag tag;
  union {
    DataWritable_Body data_writable;
    StopSending_Body stop_sending;
    HeaderReady_Body header_ready;
    DataReadable_Body data_readable;
    Reset_Body reset;
    PushPromise_Body push_promise;
    PushHeaderReady_Body push_header_ready;
    PushDataReadable_Body push_data_readable;
    PushCanceled_Body push_canceled;
    PushReset_Body push_reset;
    ConnectionClosing_Body connection_closing;
    ConnectionClosed_Body connection_closed;
    ResumptionToken_Body resumption_token;
    WebTransport_Body web_transport;
    ConnectUdp_Body connect_udp;
  };
};

struct NeqoSecretInfo {
  bool set;
  uint16_t version;
  uint16_t cipher;
  uint16_t group;
  bool resumed;
  bool early_data;
  nsCString alpn;
  uint16_t signature_scheme;
  bool ech_accepted;
};

struct NeqoCertificateInfo {
  nsTArray<nsTArray<uint8_t>> certs;
  bool stapled_ocsp_responses_present;
  nsTArray<nsTArray<uint8_t>> stapled_ocsp_responses;
  bool signed_cert_timestamp_present;
  nsTArray<uint8_t> signed_cert_timestamp;
};

struct Http3Stats {
  /// Total packets received, including all the bad ones.
  uintptr_t packets_rx;
  /// Duplicate packets received.
  uintptr_t dups_rx;
  /// Dropped packets or dropped garbage.
  uintptr_t dropped_rx;
  /// The number of packet that were saved for later processing.
  uintptr_t saved_datagrams;
  /// Total packets sent.
  uintptr_t packets_tx;
  /// Total number of packets that are declared lost.
  uintptr_t lost;
  /// Late acknowledgments, for packets that were declared lost already.
  uintptr_t late_ack;
  /// Acknowledgments for packets that contained data that was marked
  /// for retransmission when the PTO timer popped.
  uintptr_t pto_ack;
  /// Count PTOs. Single PTOs, 2 PTOs in a row, 3 PTOs in row, etc. are counted
  /// separately.
  uintptr_t pto_counts[16];
  /// The count of WouldBlock errors encountered during receive operations on the UDP socket.
  uintptr_t would_block_rx;
  /// The count of WouldBlock errors encountered during transmit operations on the UDP socket.
  uintptr_t would_block_tx;
};

using HeaderCallback = void(*)(void*, const uint8_t*, uintptr_t, const uint8_t*, uintptr_t);

extern "C" {

extern uint16_t moz_netaddr_get_family(const NetAddr *arg);

extern uint32_t moz_netaddr_get_network_order_ip(const NetAddr *arg);

extern const uint8_t *moz_netaddr_get_ipv6(const NetAddr *arg);

extern uint16_t moz_netaddr_get_network_order_port(const NetAddr *arg);

extern uintptr_t ZSTD_decompress(void *dst,
                                 uintptr_t dstCapacity,
                                 const void *src,
                                 uintptr_t compressedSize);

extern unsigned int ZSTD_isError(uintptr_t result);

extern BrotliDecoderResult BrotliDecoderDecompress(size_t encoded_size,
                                                   const unsigned char *encoded_buffer,
                                                   size_t *decoded_size,
                                                   unsigned char *decoded_buffer);

/// # Safety
///
/// See [`AtomicRefcnt::inc`].
void neqo_http3conn_addref(const NeqoHttp3Conn *conn);

/// # Safety
///
/// Manually drops a pointer without consuming pointee. The caller needs to
/// ensure no other referenecs remain. In addition safety conditions of
/// [`AtomicRefcnt::dec`] apply.
void neqo_http3conn_release(const NeqoHttp3Conn *conn);

nsresult neqo_http3conn_new(const nsACString *origin,
                            const nsACString *alpn,
                            const NetAddr *local_addr,
                            const NetAddr *remote_addr,
                            uint64_t max_table_size,
                            uint16_t max_blocked_streams,
                            uint64_t max_data,
                            uint64_t max_stream_data,
                            bool version_negotiation,
                            bool webtransport,
                            const nsACString *qlog_dir,
                            uint32_t provider_flags,
                            uint32_t idle_timeout,
                            int64_t socket,
                            bool pmtud_enabled,
                            const NeqoHttp3Conn **result);

nsresult neqo_http3conn_new_use_nspr_for_io(const nsACString *origin,
                                            const nsACString *alpn,
                                            const NetAddr *local_addr,
                                            const NetAddr *remote_addr,
                                            uint64_t max_table_size,
                                            uint16_t max_blocked_streams,
                                            uint64_t max_data,
                                            uint64_t max_stream_data,
                                            bool version_negotiation,
                                            bool webtransport,
                                            const nsACString *qlog_dir,
                                            uint32_t provider_flags,
                                            uint32_t idle_timeout,
                                            const NeqoHttp3Conn **result);

/// Process a packet.
/// packet holds packet data.
///
/// # Safety
///
/// Use of raw (i.e. unsafe) pointers as arguments.
nsresult neqo_http3conn_process_input_use_nspr_for_io(NeqoHttp3Conn *conn,
                                                      const NetAddr *remote_addr,
                                                      const nsTArray<uint8_t> *packet);

/// Process input, reading incoming datagrams from the socket and passing them
/// to the Neqo state machine.
///
/// # Safety
///
/// Marked as unsafe given exposition via FFI i.e. `extern "C"`.
ProcessInputResult neqo_http3conn_process_input(NeqoHttp3Conn *conn);

nsresult neqo_http3conn_process_output_and_send_use_nspr_for_io(NeqoHttp3Conn *conn,
                                                                void *context,
                                                                SendFunc send_func,
                                                                SetTimerFunc set_timer_func);

/// Process output, retrieving outgoing datagrams from the Neqo state machine
/// and writing them to the socket.
ProcessOutputAndSendResult neqo_http3conn_process_output_and_send(NeqoHttp3Conn *conn,
                                                                  void *context,
                                                                  SetTimerFunc set_timer_func);

void neqo_http3conn_close(NeqoHttp3Conn *conn, uint64_t error);

nsresult neqo_http3conn_fetch(NeqoHttp3Conn *conn,
                              const nsACString *method,
                              const nsACString *scheme,
                              const nsACString *host,
                              const nsACString *path,
                              const nsACString *headers,
                              uint64_t *stream_id,
                              uint8_t urgency,
                              bool incremental);

nsresult neqo_http3conn_connect(NeqoHttp3Conn *conn,
                                const nsACString *host,
                                const nsACString *headers,
                                uint64_t *stream_id,
                                uint8_t urgency,
                                bool incremental);

nsresult neqo_http3conn_priority_update(NeqoHttp3Conn *conn,
                                        uint64_t stream_id,
                                        uint8_t urgency,
                                        bool incremental);

/// # Safety
///
/// Use of raw (i.e. unsafe) pointers as arguments.
nsresult neqo_htttp3conn_send_request_body(NeqoHttp3Conn *conn,
                                           uint64_t stream_id,
                                           const uint8_t *buf,
                                           uint32_t len,
                                           uint32_t *read);

nsresult neqo_http3conn_cancel_fetch(NeqoHttp3Conn *conn, uint64_t stream_id, uint64_t error);

nsresult neqo_http3conn_reset_stream(NeqoHttp3Conn *conn, uint64_t stream_id, uint64_t error);

nsresult neqo_http3conn_stream_stop_sending(NeqoHttp3Conn *conn,
                                            uint64_t stream_id,
                                            uint64_t error);

nsresult neqo_http3conn_close_stream(NeqoHttp3Conn *conn, uint64_t stream_id);

nsresult neqo_http3conn_event(NeqoHttp3Conn *conn, Http3Event *ret_event, nsTArray<uint8_t> *data);

///
/// # Safety
///
/// Marked as unsafe given exposition via FFI i.e. `extern "C"`.
nsresult neqo_http3conn_read_response_data(NeqoHttp3Conn *conn,
                                           uint64_t stream_id,
                                           uint8_t *buf,
                                           uint32_t len,
                                           uint32_t *read,
                                           bool *fin);

nsresult neqo_http3conn_tls_info(NeqoHttp3Conn *conn, NeqoSecretInfo *sec_info);

nsresult neqo_http3conn_peer_certificate_info(NeqoHttp3Conn *conn,
                                              NeqoCertificateInfo *neqo_certs_info);

void neqo_http3conn_authenticated(NeqoHttp3Conn *conn, PRErrorCode error);

void neqo_http3conn_set_resumption_token(NeqoHttp3Conn *conn, nsTArray<uint8_t> *token);

void neqo_http3conn_set_ech_config(NeqoHttp3Conn *conn, nsTArray<uint8_t> *ech_config);

bool neqo_http3conn_is_zero_rtt(NeqoHttp3Conn *conn);

void neqo_http3conn_get_stats(NeqoHttp3Conn *conn, Http3Stats *stats);

nsresult neqo_http3conn_webtransport_create_session(NeqoHttp3Conn *conn,
                                                    const nsACString *host,
                                                    const nsACString *path,
                                                    const nsACString *headers,
                                                    uint64_t *stream_id);

nsresult neqo_http3conn_connect_udp_create_session(NeqoHttp3Conn *conn,
                                                   const nsACString *host,
                                                   const nsACString *path,
                                                   const nsACString *headers,
                                                   uint64_t *stream_id);

nsresult neqo_http3conn_webtransport_close_session(NeqoHttp3Conn *conn,
                                                   uint64_t session_id,
                                                   uint32_t error,
                                                   const nsACString *message);

nsresult neqo_http3conn_connect_udp_close_session(NeqoHttp3Conn *conn,
                                                  uint64_t session_id,
                                                  uint32_t error,
                                                  const nsACString *message);

nsresult neqo_http3conn_webtransport_create_stream(NeqoHttp3Conn *conn,
                                                   uint64_t session_id,
                                                   WebTransportStreamType stream_type,
                                                   uint64_t *stream_id);

nsresult neqo_http3conn_webtransport_send_datagram(NeqoHttp3Conn *conn,
                                                   uint64_t session_id,
                                                   nsTArray<uint8_t> *data,
                                                   uint64_t tracking_id);

nsresult neqo_http3conn_connect_udp_send_datagram(NeqoHttp3Conn *conn,
                                                  uint64_t session_id,
                                                  nsTArray<uint8_t> *data,
                                                  uint64_t tracking_id);

nsresult neqo_http3conn_webtransport_max_datagram_size(NeqoHttp3Conn *conn,
                                                       uint64_t session_id,
                                                       uint64_t *result);

/// # Safety
///
/// Use of raw (i.e. unsafe) pointers as arguments.
nsresult neqo_http3conn_webtransport_set_sendorder(NeqoHttp3Conn *conn,
                                                   uint64_t stream_id,
                                                   const int64_t *sendorder);

void neqo_encoder_addref(const NeqoEncoder *encoder);

void neqo_encoder_release(const NeqoEncoder *encoder);

void neqo_encoder_new(const NeqoEncoder **result);

void neqo_encode_byte(NeqoEncoder *encoder, uint8_t data);

void neqo_encode_varint(NeqoEncoder *encoder, uint64_t data);

void neqo_encode_uint(NeqoEncoder *encoder, uint32_t n, uint64_t data);

void neqo_encode_buffer(NeqoEncoder *encoder, const uint8_t *buf, uint32_t len);

void neqo_encode_vvec(NeqoEncoder *encoder, const uint8_t *buf, uint32_t len);

void neqo_encode_get_data(NeqoEncoder *encoder, const uint8_t **buf, uint32_t *read);

uintptr_t neqo_encode_varint_len(uint64_t v);

void neqo_decoder_addref(const NeqoDecoder *decoder);

void neqo_decoder_release(const NeqoDecoder *decoder);

void neqo_decoder_new(const uint8_t *buf, uint32_t len, const NeqoDecoder **result);

bool neqo_decode_uint32(NeqoDecoder *decoder, uint32_t *result);

bool neqo_decode_varint(NeqoDecoder *decoder, uint64_t *result);

bool neqo_decode(NeqoDecoder *decoder, uint32_t n, const uint8_t **buf, uint32_t *read);

void neqo_decode_remainder(NeqoDecoder *decoder, const uint8_t **buf, uint32_t *read);

uint64_t neqo_decoder_remaining(NeqoDecoder *decoder);

uint64_t neqo_decoder_offset(NeqoDecoder *decoder);

bool neqo_glue_test_parse_headers(const nsACString *headers_input,
                                  HeaderCallback callback,
                                  void *user_data);

}  // extern "C"

}  // namespace net
}  // namespace mozilla

#endif  // NEQO_GLUE_FFI_GENERATED_H_
