//
// File autogenerated from Include/TLSAgent.h
//

using System;
using System.Runtime.InteropServices;
using UnityEngine.Bindings;
using size_t = System.UIntPtr;

namespace Unity.TLS.LowLevel
{
    [NativeHeader("External/unitytls/builds/CSharp/BindingsUnity/TLSAgent.gen.bindings.h")]
    internal static unsafe partial class Binding
    {
        public const int UNITYTLS_SUCCESS = 0;
        /// <summary>One of the arguments has an invalid value (e.g. null where not allowed)</summary>
        public const int UNITYTLS_INVALID_ARGUMENT = 1;
        /// <summary>The passed data does not have a valid format.</summary>
        public const int UNITYTLS_INVALID_FORMAT = 2;
        /// <summary>Invalid password</summary>
        public const int UNITYTLS_INVALID_PASSWORD = 3;
        /// <summary>The object operating being operated on is not in a state that allows this function call.</summary>
        public const int UNITYTLS_INVALID_STATE = 4;
        /// <summary>A passed buffer was not large enough.</summary>
        public const int UNITYTLS_BUFFER_OVERFLOW = 5;
        /// <summary>Out of memory error</summary>
        public const int UNITYTLS_OUT_OF_MEMORY = 6;
        /// <summary>Internal implementation error.</summary>
        public const int UNITYTLS_INTERNAL_ERROR = 7;
        /// <summary>The requested action is not supported on the current platform/implementation.</summary>
        public const int UNITYTLS_NOT_SUPPORTED = 8;
        /// <summary>Failed to generate requested amount of entropy data.</summary>
        public const int UNITYTLS_ENTROPY_SOURCE_FAILED = 9;
        /// <summary>The operation is not possible because the stream between the peers was closed.</summary>
        public const int UNITYTLS_STREAM_CLOSED = 10;
        /// <summary>error in parse_der</summary>
        public const int UNITYTLS_DER_PARSE_ERROR = 11;
        /// <summary>error parsing key</summary>
        public const int UNITYTLS_KEY_PARSE_ERROR = 12;
        /// <summary>SSL setup failed</summary>
        public const int UNITYTLS_SSL_ERROR = 13;
        public const int UNITYTLS_USER_CUSTOM_ERROR_START = 1048576;
        /// <summary>Can be set by the user to signal that a call (e.g. read/write callback) would block and needs to be called again.</summary>
        public const int UNITYTLS_USER_WOULD_BLOCK = 1048577;
        /// <summary>Refinement on UNITYTLS_USER_WOULD_BLOCK</summary>
        public const int UNITYTLS_USER_WOULD_BLOCK_READ = 1048578;
        /// <summary>Refinement on UNITYTLS_USER_WOULD_BLOCK</summary>
        public const int UNITYTLS_USER_WOULD_BLOCK_WRITE = 1048579;
        /// <summary>Can be set by the user to indicate a failed read operation.</summary>
        public const int UNITYTLS_USER_READ_FAILED = 1048580;
        /// <summary>Can be set by the user to indicate a failed write operation.</summary>
        public const int UNITYTLS_USER_WRITE_FAILED = 1048581;
        /// <summary>Can be set by the user to indicate a generic error.</summary>
        public const int UNITYTLS_USER_UNKNOWN_ERROR = 1048582;
        /// <summary>Not an error - need to verify the validity of a connecting client.</summary>
        public const int UNITYTLS_SSL_NEEDS_VERIFY = 1048583;
        /// <summary>Not an error - we are in the process of handshake stepping.</summary>
        public const int UNITYTLS_HANDSHAKE_STEP = 1048584;
        public const int UNITYTLS_USER_CUSTOM_ERROR_END = 2097152;
        public const int UNITYTLS_LOGLEVEL_MIN = 0;
        public const int UNITYTLS_LOGLEVEL_FATAL = 0;
        public const int UNITYTLS_LOGLEVEL_ERROR = 1;
        public const int UNITYTLS_LOGLEVEL_WARN = 2;
        public const int UNITYTLS_LOGLEVEL_INFO = 3;
        public const int UNITYTLS_LOGLEVEL_DEBUG = 4;
        public const int UNITYTLS_LOGLEVEL_TRACE = 5;
        public const int UNITYTLS_LOGLEVEL_MAX = 5;
        public const int UNITYTLS_SSL_HANDSHAKE_HELLO_REQUEST = 0;
        public const int UNITYTLS_SSL_HANDSHAKE_CLIENT_HELLO = 1;
        public const int UNITYTLS_SSL_HANDSHAKE_SERVER_HELLO = 2;
        public const int UNITYTLS_SSL_HANDSHAKE_SERVER_CERTIFICATE = 3;
        public const int UNITYTLS_SSL_HANDSHAKE_SERVER_KEY_EXCHANGE = 4;
        public const int UNITYTLS_SSL_HANDSHAKE_CERTIFICATE_REQUEST = 5;
        public const int UNITYTLS_SSL_HANDSHAKE_SERVER_HELLO_DONE = 6;
        public const int UNITYTLS_SSL_HANDSHAKE_CLIENT_CERTIFICATE = 7;
        public const int UNITYTLS_SSL_HANDSHAKE_CLIENT_KEY_EXCHANGE = 8;
        public const int UNITYTLS_SSL_HANDSHAKE_CERTIFICATE_VERIFY = 9;
        public const int UNITYTLS_SSL_HANDSHAKE_CLIENT_CHANGE_CIPHER_SPEC = 10;
        public const int UNITYTLS_SSL_HANDSHAKE_CLIENT_FINISHED = 11;
        public const int UNITYTLS_SSL_HANDSHAKE_SERVER_CHANGE_CIPHER_SPEC = 12;
        public const int UNITYTLS_SSL_HANDSHAKE_SERVER_FINISHED = 13;
        public const int UNITYTLS_SSL_HANDSHAKE_FLUSH_BUFFERS = 14;
        public const int UNITYTLS_SSL_HANDSHAKE_WRAPUP = 15;
        public const int UNITYTLS_SSL_HANDSHAKE_OVER = 16;
        public const int UNITYTLS_SSL_HANDSHAKE_SERVER_NEW_SESSION_TICKET = 17;
        public const int UNITYTLS_SSL_HANDSHAKE_HELLO_VERIFY_REQUIRED = 18;
        /// <summary>Number of constant definitions</summary>
        public const int UNITYTLS_SSL_HANDSHAKE_COUNT = 19;
        /// <summary>Deprecated: for backward compatibility only</summary>
        public const int UNITYTLS_SSL_HANDSHAKE_BEGIN = 0;
        /// <summary>Deprecated: for backward compatibility only</summary>
        public const int UNITYTLS_SSL_HANDSHAKE_DONE = 16;
        /// <summary>Deprecated: for backward compatibility only</summary>
        public const int UNITYTLS_SSL_HANDSHAKE_HANDSHAKE_FLUSH_BUFFERS = 14;
        /// <summary>Deprecated: for backward compatibility only</summary>
        public const int UNITYTLS_SSL_HANDSHAKE_HANDSHAKE_WRAPUP = 15;
        /// <summary>Deprecated: for backward compatibility only</summary>
        public const int UNITYTLS_SSL_HANDSHAKE_HANDSHAKE_OVER = 16;
        [StructLayout(LayoutKind.Sequential)]
        public struct unitytls_errorstate
        {
            public uint magic;
            public uint code;
            /// <summary>Implementation specific error code/handle.</summary>
            public ulong reserved;
        }
        /// <summary>struct that encapsulates a data pointer and data length.</summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct unitytls_dataRef
        {
            public byte* dataPtr;
            public size_t dataLen;
        }
        public const int UnityTLSClientAuth_None = 0;
        public const int UnityTLSClientAuth_Optional = 1;
        public const int UnityTLSClientAuth_Required = 2;
        public const int UnityTLSRole_None = 0;
        public const int UnityTLSRole_Server = 1;
        public const int UnityTLSRole_Client = 2;
        public const int UnityTLSTransportProtocol_Stream = 0;
        public const int UnityTLSTransportProtocol_Datagram = 1;
        public const int UnityTLSClientState_None = 0;
        public const int UnityTLSClientState_Init = 1;
        public const int UnityTLSClientState_Handshake = 2;
        public const int UnityTLSClientState_Messaging = 3;
        public const int UnityTLSClientState_Fail = 64;
        /// <summary>UNITYTLS_CLIENT => UTP (Upstream Client)</summary>
        /// <remarks>
        /// This is the callback into application land for the next data consumer. Typically this will be a pipeline
        /// (or protocol)? tbd.  This is how we push data up into the next "stage" after decryption.
        /// If status in non-zero then it represents an error case, and will be represented by a unitytls_client_error_code.
        /// It may be preferable to use a different reporting nechanism, this is merely the POC.
        /// </remarks>
        /// <param name="userData">pointer to user data, opaque to this system</param>
        /// <param name="data">data read</param>
        /// <param name="dataLen">size of data read</param>
        /// <param name="status">reserved, currently unused</param>
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void unitytls_client_on_data_callback(IntPtr arg0, byte* arg1, size_t arg2, uint arg3);
        /// <summary>UNITYTLS_CLIENT => TRANSPORT</summary>
        /// <remarks>
        /// To be called by unitytls_client when we want to send data directly through the transport (just encrypted by UnityTLS).
        /// Occurs downstream from unitytls_client_send_data()
        /// </remarks>
        /// <param name="userData">pointer to user data, opaque to this system</param>
        /// <param name="data">data to write</param>
        /// <param name="dataLen">size of data to write</param>
        /// <param name="status">reserved, currently unused</param>
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate int unitytls_client_data_send_callback(IntPtr arg0, byte* arg1, size_t arg2, uint arg3);
        /// <summary>Blocking callback to get data from the transport.</summary>
        /// <param name="userData">pointer to user data, opaque to this system</param>
        /// <param name="data">data buffer</param>
        /// <param name="dataLen">size of data buffer</param>
        /// <param name="status">reserved, currently unused</param>
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate int unitytls_client_data_receive_callback(IntPtr arg0, byte* arg1, size_t arg2, uint arg3);
        /// <summary>Callback to get data from the transport that provides for a timeout.</summary>
        /// <param name="userData">pointer to user data, opaque to this system</param>
        /// <param name="data">data buffer</param>
        /// <param name="dataLen">size of data buffer</param>
        /// <param name="timeout">timeout value, how long to wait for a read.</param>
        /// <param name="status">reserved, currently unused</param>
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate int unitytls_client_data_receive_timeout_callback(IntPtr arg0, byte* arg1, size_t arg2, uint arg3, uint arg4);
        /// <summary>Callback to consume logging events.</summary>
        /// <param name="level">logging level, from unitytls_log_level</param>
        /// <param name="filename">source fileename at call site</param>
        /// <param name="lineNumber">line number at call site</param>
        /// <param name="functionName">function name at call site</param>
        /// <param name="msg">the logging event message body</param>
        /// <param name="msgLen">size of the message. It is usually null-terminated.</param>
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void unitytls_client_log_callback(int arg0, byte* arg1, size_t arg2, byte* arg3, byte* arg4, size_t arg5);
        /// <summary>Client config</summary>
        /// <remarks>
        /// We opt for a config driven system as opposed to a set of routines that must be called. This makes it easier to
        /// determine what needs to be set. Current implementation assumes caller maintains ownership - we keep a reference only.
        /// </remarks>
        [StructLayout(LayoutKind.Sequential)]
        public struct unitytls_client_config
        {
            /// <summary>common (client/server) certificate</summary>
            public unitytls_dataRef caPEM;
            /// <summary>server (or client) own certificate</summary>
            public unitytls_dataRef serverPEM;
            /// <summary>server (or client) own private key</summary>
            public unitytls_dataRef privateKeyPEM;
            /// <summary>server-only policy regarding client authentication</summary>
            public uint clientAuth;
            /// <summary>the transport protocol for unity tls</summary>
            public uint transportProtocol;
            /// <summary>pre-shared key.</summary>
            public unitytls_dataRef psk;
            /// <summary>expected identity name</summary>
            public unitytls_dataRef pskIdentity;
            // Delegates are managed types, putting it here directly would prevent us from creating pointers to this struct.
            // Use System.Runtime.InteropServices.GetFunctionPointerForDelegate to generate IntPtr from the original delegate.
            public IntPtr onDataCB; // unitytls_client_on_data_callback
            // Delegates are managed types, putting it here directly would prevent us from creating pointers to this struct.
            // Use System.Runtime.InteropServices.GetFunctionPointerForDelegate to generate IntPtr from the original delegate.
            public IntPtr dataSendCB; // unitytls_client_data_send_callback
            // Delegates are managed types, putting it here directly would prevent us from creating pointers to this struct.
            // Use System.Runtime.InteropServices.GetFunctionPointerForDelegate to generate IntPtr from the original delegate.
            public IntPtr dataReceiveCB; // unitytls_client_data_receive_callback
            // Delegates are managed types, putting it here directly would prevent us from creating pointers to this struct.
            // Use System.Runtime.InteropServices.GetFunctionPointerForDelegate to generate IntPtr from the original delegate.
            public IntPtr dataReceiveTimeoutCB; // unitytls_client_data_receive_timeout_callback
            /// <summary>for invoking callbacks in transport (network interface)</summary>
            public IntPtr transportUserData;
            /// <summary>for invoking callbacks into application land.</summary>
            public IntPtr applicationUserData;
            /// <summary>if non-zero unitytls_client_handshake returns on step; caller should recall immediately. See comment in unitytls_client_handshake</summary>
            public int handshakeReturnsOnStep;
            /// <summary>if non-zero unitytls_client_handshake returns if it would block on io; caller should recall immediately. See comment in unitytls_client_handshake</summary>
            public int handshakeReturnsIfWouldBlock;
            /// <summary>timeout in ms for ssl reads.</summary>
            public uint ssl_read_timeout_ms;
            /// <summary>server's hostname's name</summary>
            public byte* hostname;
            /// <summary>one of unitytls_log_level_t above.</summary>
            public uint tracelevel;
            /// <summary>callback for logging statements.</summary>
            // Delegates are managed types, putting it here directly would prevent us from creating pointers to this struct.
            // Use System.Runtime.InteropServices.GetFunctionPointerForDelegate to generate IntPtr from the original delegate.
            public IntPtr logCallback; // unitytls_client_log_callback
            /// <summary>Initial ssl handshake minimum timeout value in milliseconds. Default is 1000 (1 sec)</summary>
            public uint ssl_handshake_timeout_min;
            /// <summary>Initial ssl handshake maximum timeout value in milliseconds. Default is 60000 (60 seconds)</summary>
            public uint ssl_handshake_timeout_max;
            /// <summary>Maximum size of UnityTLS messages. Note that user payloads too large to fit will result in errors.</summary>
            public ushort mtu;
        }
        /// <summary>
        /// Client wrapper struct for holding instance and state data.
        /// It is expected that the caller own this as it is required for most calls here.
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct unitytls_client
        {
            /// <summary>server or client</summary>
            public uint role;
            /// <summary>opaque for now</summary>
            public uint state;
            /// <summary>current handshakestate</summary>
            public uint handshakeState;
            /// <summary>unitytls_tlsctx -internal unity tls ctx represents connection state, opaque.</summary>
            public IntPtr ctx;
            /// <summary>user configuration struct</summary>
            public unitytls_client_config* config;
            /// <summary>internal class wrapper (TLSClientAgent)</summary>
            public IntPtr internalCtx;
        }
        /// <summary>UTP (Upstream Client) => UNITYTLS_CLIENT</summary>
        /// <remarks>
        /// This is the entry point to send data through UnityTLS. Note that this will in turn cause unitytls_client_data_send_callback
        /// to be invoked to send the encrypted data out through the transport.  This is not a callback.
        /// </remarks>
        /// <param name="clientInstance">pointer to client instance</param>
        /// <param name="data">data to write</param>
        /// <param name="dataLen">size of data to write</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern uint unitytls_client_send_data(unitytls_client* clientInstance, byte* data, size_t dataLen);
        /// <summary>UTP (Upstream Client) => UNITYTLS_CLIENT</summary>
        /// <remarks>
        /// This is a call required to pump data from the transport. TODO fill out path here
        /// This is not a callback.
        /// maps to unitytls_tlsctx_read
        /// </remarks>
        /// <param name="clientInstance">pointer to client instance</param>
        /// <param name="buffer">destination buffer</param>
        /// <param name="dataLen">size of destination buffer</param>
        /// <param name="bytesRead">the number of bytes written to buffer</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern uint unitytls_client_read_data(unitytls_client* clientInstance, byte* buffer, size_t bufferLen, size_t* bytesRead);
        /// <summary>Add ciphersuites if you want to set a subset of suites to support</summary>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        /// <param name="suite">the enumeration value for the ciphersuite to add</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern void unitytls_client_add_ciphersuite(unitytls_client* clientInstance, uint suite);
        /// <summary>Retreive the nth ciphersuite in our config</summary>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        /// <param name="ndx">the index of the desired suite.</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern uint unitytls_client_get_ciphersuite(unitytls_client* clientInstance, int ndx);
        /// <summary>Get the count of ciphersuites in our config</summary>
        /// <remarks>Meant for use with unitytls_client_get_ciphersuite()</remarks>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern int unitytls_client_get_ciphersuite_cnt(unitytls_client* clientInstance);
        /// <summary>Intitialize a config instance. Should be used prior to populating.</summary>
        /// <param name="client">pointer to the (opaque) client instance</param>
        /// <param name="suite">the enumeration value for the ciphersuite to add</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern void unitytls_client_init_config(unitytls_client_config* config);
        /// <summary>Create and initialize a client instance.</summary>
        /// <param name="role">one of client/server - the role as pertains to connection establish and handshake</param>
        /// <param name="config">pointer to the config you hopefully filled out.</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern unitytls_client* unitytls_client_create(uint role, unitytls_client_config* config);
        /// <summary>Initialize the unitytls subsystem and unitytls</summary>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern void unitytls_client_destroy(unitytls_client* clientInstance);
        /// <summary>Initialize the unitytls subsystem and unitytls</summary>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern int unitytls_client_init(unitytls_client* clientInstance);
        /// <summary>
        /// Callback invoked when the transport would block on a read. SHour return 1 (non-zero) if we want to contine
        /// the handshhake or 0  if we should return
        /// </summary>
        /// <param name="ctx">the client instance context</param>
        /// <param name="userData">cargo pointer supplied in unitytls_tlsctx_process_handshake_ex() userData parameter</param>
        /// <param name="blockingType">one of UNITYTLS_ERR_SSL_WANT_READ or UNITYTLS_ERR_SSL_WANT_WRITE</param>
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate int unitytls_tlsctx_handshake_on_blocking_callback(unitytls_client* arg0, IntPtr arg1, int arg2);
        /// <summary>Perform the client hello and handshake.</summary>
        /// <remarks>
        /// The handshake can run to completion, or can return on either the SSL step or when IO would block. This behavior is controlled by the
        /// handshakeReturnsOnStep and handshakeReturnsIfWouldBlock config settings; if handshakeReturnsIfWouldBlock is non-zero we return if we would block on io,
        /// and if handshakeReturnsOnStep is non-zero we return on all steps (blocking IO included). Caller is expected to call us again pronto barring errors.
        /// If handshakeReturnsOnStep
        /// If handshakeReturnsIfWouldBlock is non-zero (default) an IO call that would block causes this to return with one of UNITYTLS_ERR_SSL_WANT_WRITE or
        /// UNITYTLS_ERR_SSL_WANT_READ.
        /// </remarks>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        /// <param name="onBlockingCB">if supplied will be called if a read or write blocks at the transport. If null no callback will be made and we will just retry.</param>
        /// <param name="userData">
        /// user data pointer passed to onBlockingCB callback
        /// return the status of the operation:
        /// UNITYTLS_SUCCESS - yay!
        /// - UNITYTLS_HANDSHAKE_STEP - this is not an error, see blelow.
        /// - UNITYTLS_USER_WOULD_BLOCK, UNITYTLS_USER_WOULD_BLOCK_READ, UNITYTLS_USER_WOULD_BLOCK_WRITE - this is not an error, see below.
        /// - UNITYTLS_SSL_NEEDS_VERIFY - this is not an error, see below.
        /// - UNITYTLS_SSL_ERROR - the handshake failed. Look at m_errorState for internal details.
        /// </param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern uint unitytls_client_handshake(unitytls_client* clientInstance);
        /// <summary>Sets the cookie info (server only) required for peer verification. This must be called once prior to unitytls_client_handshake on the server side.</summary>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        /// <param name="peerIdDataPtr">(server only): a pointer to a string of bytes that uniquely identifies the client. Used for cookie nmanagement.</param>
        /// <param name="peerIdDataLen">(server only): length of byte array</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern uint unitytls_client_set_cookie_info(unitytls_client* clientInstance, byte* peerIdDataPtr, int peerIdDataLen);
        /// <summary>Retreive the current agent handshake state, see unitytls_ssl_handshake_state_t above.</summary>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern uint unitytls_client_get_handshake_state(unitytls_client* clientInstance);
        /// <summary>Retrieves the last error state reported by unitytls internally.</summary>
        /// <remarks>
        /// The return value is the unitytls_error_code value and the value written to reserved is the internal implmentation-specific value. In general, reserved is to be
        /// ignored in favor of the return value.
        /// If client is invalid and/and we would not retrieve these values UNITYTLS_USER_CUSTOM_ERROR_END is returned and
        /// reserved left untouched.
        /// </remarks>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        /// <param name="reserved">(out) pointer to an int where the implementation-specific error code value will be written</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern uint unitytls_client_get_errorsState(unitytls_client* clientInstance, ulong* reserved);
        /// <summary>Retreive the current agent state, see UnityTLSClientState_t above.</summary>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern uint unitytls_client_get_state(unitytls_client* clientInstance);
        /// <summary>Retreive the current agent role, see unitytls_client_role_t above.</summary>
        /// <param name="clientInstance">pointer to the (opaque) client instance</param>
        [FreeFunction(IsThreadSafe = true)]
        public static extern uint unitytls_client_get_role(unitytls_client* clientInstance);
    }
}
