/*
 Copyright 2023 Google LLC
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/


#pragma once

/* Generated with cbindgen:0.24.5 */

/*
 WARNING: this file is autogenerated by cbindgen. Don't modify this manually.
 Additionally, you should _not_ rely upon the layouts of the generated
 structs and unions if you want your code to be forward-compatible,
 unless a given type explicitly states in its documentation that it has
 a guaranteed forward-compatible layout.
 Instead, you should use _only_ the provided exported function symbols.
*/

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

/**
 * Result type for trying to add a credential to a credential-slab.
 */
enum np_ffi_AddCredentialToSlabResult {
  /**
   * We succeeded in adding the credential to the slab.
   */
  NP_FFI_ADD_CREDENTIAL_TO_SLAB_RESULT_SUCCESS = 0,
  /**
   * The handle to the slab was actually invalid.
   */
  NP_FFI_ADD_CREDENTIAL_TO_SLAB_RESULT_INVALID_HANDLE = 1,
};
typedef uint8_t np_ffi_AddCredentialToSlabResult;

/**
 * The possible boolean action types which can be present in an Actions data element
 */
enum np_ffi_BooleanActionType {
  NP_FFI_BOOLEAN_ACTION_TYPE_ACTIVE_UNLOCK = 8,
  NP_FFI_BOOLEAN_ACTION_TYPE_NEARBY_SHARE = 9,
  NP_FFI_BOOLEAN_ACTION_TYPE_INSTANT_TETHERING = 10,
  NP_FFI_BOOLEAN_ACTION_TYPE_PHONE_HUB = 11,
  NP_FFI_BOOLEAN_ACTION_TYPE_PRESENCE_MANAGER = 12,
  NP_FFI_BOOLEAN_ACTION_TYPE_FINDER = 13,
  NP_FFI_BOOLEAN_ACTION_TYPE_FAST_PAIR_SASS = 14,
};
typedef uint8_t np_ffi_BooleanActionType;

/**
 * Discriminant for `CreateCredentialBookResult`
 */
enum np_ffi_CreateCredentialBookResultKind {
  /**
   * We created a new credential book behind the given handle.
   * The associated payload may be obtained via
   * `CreateCredentialBookResult#into_success()`.
   */
  NP_FFI_CREATE_CREDENTIAL_BOOK_RESULT_KIND_SUCCESS = 0,
  /**
   * There was no space left to create a new credential book
   */
  NP_FFI_CREATE_CREDENTIAL_BOOK_RESULT_KIND_NO_SPACE_LEFT = 1,
  /**
   * The slab that we tried to create a credential-book from
   * actually was an invalid handle.
   */
  NP_FFI_CREATE_CREDENTIAL_BOOK_RESULT_KIND_INVALID_SLAB_HANDLE = 2,
};
typedef uint8_t np_ffi_CreateCredentialBookResultKind;

/**
 * Discriminant for `CreateCredentialSlabResult`
 */
enum np_ffi_CreateCredentialSlabResultKind {
  /**
   * There was no space left to create a new credential slab
   */
  NP_FFI_CREATE_CREDENTIAL_SLAB_RESULT_KIND_NO_SPACE_LEFT = 0,
  /**
   * We created a new credential slab behind the given handle.
   * The associated payload may be obtained via
   * `CreateCredentialSlabResult#into_success()`.
   */
  NP_FFI_CREATE_CREDENTIAL_SLAB_RESULT_KIND_SUCCESS = 1,
};
typedef uint8_t np_ffi_CreateCredentialSlabResultKind;

/**
 * A result-type enum which tells the caller whether/not a deallocation
 * succeeded or failed due to the requested handle not being present.
 */
typedef enum {
  /**
   * The requested handle to deallocate was not present in the map
   */
  NP_FFI_DEALLOCATE_RESULT_NOT_PRESENT = 0,
  /**
   * The object behind the handle was successfully deallocated
   */
  NP_FFI_DEALLOCATE_RESULT_SUCCESS = 1,
} np_ffi_DeallocateResult;

/**
 * Discriminant for `DeserializeAdvertisementResult`.
 */
enum np_ffi_DeserializeAdvertisementResultKind {
  /**
   * Deserializing the advertisement failed, for some reason or another.
   */
  NP_FFI_DESERIALIZE_ADVERTISEMENT_RESULT_KIND_ERROR = 0,
  /**
   * The advertisement was correctly deserialized, and it's a V0 advertisement.
   * `DeserializeAdvertisementResult#into_v0()` is the corresponding cast
   * to the associated enum variant.
   */
  NP_FFI_DESERIALIZE_ADVERTISEMENT_RESULT_KIND_V0 = 1,
  /**
   * The advertisement was correctly deserialized, and it's a V1 advertisement.
   * `DeserializeAdvertisementResult#into_v1()` is the corresponding cast
   * to the associated enum variant.
   */
  NP_FFI_DESERIALIZE_ADVERTISEMENT_RESULT_KIND_V1 = 2,
};
typedef uint8_t np_ffi_DeserializeAdvertisementResultKind;

/**
 * Discriminant for possible results of V0 advertisement deserialization
 */
enum np_ffi_DeserializedV0AdvertisementKind {
  /**
   * The deserialized V0 advertisement was legible.
   * The associated payload may be obtained via
   * `DeserializedV0Advertisement#into_legible`.
   */
  NP_FFI_DESERIALIZED_V0_ADVERTISEMENT_KIND_LEGIBLE = 0,
  /**
   * The deserialized V0 advertisement is illegible,
   * likely meaning that the receiver does not hold
   * the proper credentials to be able to read
   * the received advertisement.
   */
  NP_FFI_DESERIALIZED_V0_ADVERTISEMENT_KIND_NO_MATCHING_CREDENTIALS = 1,
};
typedef uint8_t np_ffi_DeserializedV0AdvertisementKind;

/**
 * Discriminant for deserialized information about the V0
 * identity utilized by a deserialized V0 advertisement.
 */
enum np_ffi_DeserializedV0IdentityKind {
  /**
   * The deserialized identity was a plaintext identity.
   */
  NP_FFI_DESERIALIZED_V0_IDENTITY_KIND_PLAINTEXT = 0,
  /**
   * The deserialized identity was some decrypted identity.
   */
  NP_FFI_DESERIALIZED_V0_IDENTITY_KIND_DECRYPTED = 1,
};
typedef uint8_t np_ffi_DeserializedV0IdentityKind;

/**
 * Discriminant for `DeserializedV1Identity`.
 */
enum np_ffi_DeserializedV1IdentityKind {
  /**
   * The deserialized v1 identity was plaintext
   */
  NP_FFI_DESERIALIZED_V1_IDENTITY_KIND_PLAINTEXT = 0,
  /**
   * The deserialized v1 identity corresponded
   * to some kind of decrypted identity.
   */
  NP_FFI_DESERIALIZED_V1_IDENTITY_KIND_DECRYPTED = 1,
};
typedef uint8_t np_ffi_DeserializedV1IdentityKind;

/**
 * Discriminant of `GetV0DEResult`.
 */
enum np_ffi_GetV0DEResultKind {
  /**
   * The attempt to get the DE succeeded.
   * The associated payload may be obtained via
   * `GetV0DEResult#into_success`.
   */
  NP_FFI_GET_V0DE_RESULT_KIND_SUCCESS = 0,
  /**
   * The attempt to get the DE failed,
   * possibly due to the requested index being
   * out-of-bounds or due to the advertisement
   * having been previously deallocated.
   */
  NP_FFI_GET_V0DE_RESULT_KIND_ERROR = 1,
};
typedef uint8_t np_ffi_GetV0DEResultKind;

/**
 * Discriminant for the `GetV1DEResult` enum.
 */
enum np_ffi_GetV1DEResultKind {
  /**
   * Attempting to get the DE at the given position failed,
   * possibly due to the index being out-of-bounds or due
   * to the whole advertisement having been previously deallocated.
   */
  NP_FFI_GET_V1DE_RESULT_KIND_ERROR = 0,
  /**
   * Attempting to get the DE at the given position succeeded.
   * The underlying DE may be extracted with `GetV1DEResult#into_success`.
   */
  NP_FFI_GET_V1DE_RESULT_KIND_SUCCESS = 1,
};
typedef uint8_t np_ffi_GetV1DEResultKind;

/**
 * Discriminant for `GetV1SectionResult`
 */
enum np_ffi_GetV1SectionResultKind {
  /**
   * The attempt to get the section failed,
   * possibly due to the section index being
   * out-of-bounds or due to the underlying
   * advertisement having already been deallocated.
   */
  NP_FFI_GET_V1_SECTION_RESULT_KIND_ERROR = 0,
  /**
   * The attempt to get the section succeeded.
   * The wrapped section may be obtained via
   * `GetV1SectionResult#into_success`.
   */
  NP_FFI_GET_V1_SECTION_RESULT_KIND_SUCCESS = 1,
};
typedef uint8_t np_ffi_GetV1SectionResultKind;

/**
 * Structure for categorized reasons for why a NP C FFI call may
 * be panicking.
 */
enum np_ffi_PanicReason {
  /**
   * Some enum cast to a variant failed. Utilized
   * for failed enum casts of all enums.
   *
   * (That is, this is the catch-all panic reason for enum
   * casts where there is not a more specific reason
   * in some other variant of this enum.)
   */
  NP_FFI_PANIC_REASON_ENUM_CAST_FAILED = 0,
  /**
   * The panic handler is used to assert conditions are true to avoid programmer errors.
   * If a failed assert condition is hit, this panic handler is invoked with this reason.
   */
  NP_FFI_PANIC_REASON_ASSERT_FAILED = 1,
  /**
   * Error returned if action bits inside of a V0Actions struct are invalid. If the struct was
   * created by this deserializer, the bits will always be valid, they are only invalid if
   * a user reaches in and changes them to something invalid.
   */
  NP_FFI_PANIC_REASON_INVALID_ACTION_BITS = 2,
};
typedef uint8_t np_ffi_PanicReason;

/**
 * Discriminant for `V0DataElement`.
 */
enum np_ffi_V0DataElementKind {
  /**
   * A transmission Power (Tx Power) data-element.
   * The associated payload may be obtained via
   * `V0DataElement#into_tx_power`.
   */
  NP_FFI_V0_DATA_ELEMENT_KIND_TX_POWER = 0,
  /**
   * The Actions data-element.
   * The associated payload may be obtained via
   * `V0DataElement#into_actions`.
   */
  NP_FFI_V0_DATA_ELEMENT_KIND_ACTIONS = 1,
};
typedef uint8_t np_ffi_V0DataElementKind;

/**
 *A `#[repr(C)]` handle to a value of type `super::CredentialBookInternals`.
 */
typedef struct {
  uint64_t handle_id;
} np_ffi_CredentialBook;

/**
 * Result type for `create_credential_book`
 */
enum np_ffi_CreateCredentialBookResult_Tag {
  NP_FFI_CREATE_CREDENTIAL_BOOK_RESULT_SUCCESS = 0,
  NP_FFI_CREATE_CREDENTIAL_BOOK_RESULT_NO_SPACE_LEFT = 1,
  NP_FFI_CREATE_CREDENTIAL_BOOK_RESULT_INVALID_SLAB_HANDLE = 2,
};
typedef uint8_t np_ffi_CreateCredentialBookResult_Tag;

typedef union {
  np_ffi_CreateCredentialBookResult_Tag tag;
  struct {
    np_ffi_CreateCredentialBookResult_Tag success_tag;
    np_ffi_CredentialBook success;
  };
} np_ffi_CreateCredentialBookResult;

/**
 *A `#[repr(C)]` handle to a value of type `super::CredentialSlabInternals`.
 */
typedef struct {
  uint64_t handle_id;
} np_ffi_CredentialSlab;

/**
 * Result type for `create_credential_slab`
 */
typedef enum {
  NP_FFI_CREATE_CREDENTIAL_SLAB_RESULT_NO_SPACE_LEFT,
  NP_FFI_CREATE_CREDENTIAL_SLAB_RESULT_SUCCESS,
} np_ffi_CreateCredentialSlabResult_Tag;

typedef struct {
  np_ffi_CreateCredentialSlabResult_Tag tag;
  union {
    struct {
      np_ffi_CredentialSlab success;
    };
  };
} np_ffi_CreateCredentialSlabResult;

/**
 * Cryptographic information about a particular V0 discovery credential
 * necessary to match and decrypt encrypted V0 advertisements.
 */
typedef struct {
  uint8_t key_seed[32];
  uint8_t legacy_metadata_key_hmac[32];
} np_ffi_V0DiscoveryCredential;

/**
 * A representation of a MatchedCredential which is passable across the FFI boundary
 */
typedef struct {
  uint32_t cred_id;
  const uint8_t *encrypted_metadata_bytes_buffer;
  uintptr_t encrypted_metadata_bytes_len;
} np_ffi_FfiMatchedCredential;

/**
 * Representation of a V0 credential that contains additional data to provide back to caller once it
 * is matched. The credential_id can be used by the caller to correlate it back to the full
 * credentials details.
 */
typedef struct {
  np_ffi_V0DiscoveryCredential discovery_cred;
  np_ffi_FfiMatchedCredential matched_cred;
} np_ffi_V0MatchableCredential;

/**
 * Cryptographic information about a particular V1 discovery credential
 * necessary to match and decrypt encrypted V1 advertisement sections.
 */
typedef struct {
  uint8_t key_seed[32];
  uint8_t expected_unsigned_metadata_key_hmac[32];
  uint8_t expected_signed_metadata_key_hmac[32];
  uint8_t pub_key[32];
} np_ffi_V1DiscoveryCredential;

/**
 * Representation of a V1 credential that contains additional data to provide back to caller once it
 * is matched. The credential_id can be used by the caller to correlate it back to the full
 * credentials details.
 */
typedef struct {
  np_ffi_V1DiscoveryCredential discovery_cred;
  np_ffi_FfiMatchedCredential matched_cred;
} np_ffi_V1MatchableCredential;

/**
 *A `#[repr(C)]` handle to a value of type `super::V0PayloadInternals`.
 */
typedef struct {
  uint64_t handle_id;
} np_ffi_V0Payload;

/**
 * Represents a deserialized V0 advertisement whose DE contents may be read
 */
typedef struct {
  uint8_t num_des;
  np_ffi_V0Payload payload;
  np_ffi_DeserializedV0IdentityKind identity_kind;
} np_ffi_LegibleDeserializedV0Advertisement;

/**
 * Represents a deserialized V0 advertisement
 */
typedef enum {
  NP_FFI_DESERIALIZED_V0_ADVERTISEMENT_LEGIBLE,
  NP_FFI_DESERIALIZED_V0_ADVERTISEMENT_NO_MATCHING_CREDENTIALS,
} np_ffi_DeserializedV0Advertisement_Tag;

typedef struct {
  np_ffi_DeserializedV0Advertisement_Tag tag;
  union {
    struct {
      np_ffi_LegibleDeserializedV0Advertisement legible;
    };
  };
} np_ffi_DeserializedV0Advertisement;

/**
 *A `#[repr(C)]` handle to a value of type `super::LegibleV1SectionsInternals`.
 */
typedef struct {
  uint64_t handle_id;
} np_ffi_LegibleV1Sections;

/**
 * Representation of a deserialized V1 advertisement
 */
typedef struct {
  uint8_t num_legible_sections;
  uint8_t num_undecryptable_sections;
  np_ffi_LegibleV1Sections legible_sections;
} np_ffi_DeserializedV1Advertisement;

/**
 * The result of calling `np_ffi_deserialize_advertisement`.
 * Must be explicitly deallocated after use with
 * a corresponding `np_ffi_deallocate_deserialize_advertisement_result`
 */
enum np_ffi_DeserializeAdvertisementResult_Tag {
  /**
   * Deserializing the advertisement failed, for some reason or another.
   * `DeserializeAdvertisementResultKind::Error` is the associated enum tag.
   */
  NP_FFI_DESERIALIZE_ADVERTISEMENT_RESULT_ERROR,
  /**
   * The advertisement was correctly deserialized, and it's a V0 advertisement.
   * `DeserializeAdvertisementResultKind::V0` is the associated enum tag.
   */
  NP_FFI_DESERIALIZE_ADVERTISEMENT_RESULT_V0,
  /**
   * The advertisement was correctly deserialized, and it's a V1 advertisement.
   * `DeserializeAdvertisementResultKind::V1` is the associated enum tag.
   */
  NP_FFI_DESERIALIZE_ADVERTISEMENT_RESULT_V1,
};
typedef uint8_t np_ffi_DeserializeAdvertisementResult_Tag;

typedef union {
  np_ffi_DeserializeAdvertisementResult_Tag tag;
  struct {
    np_ffi_DeserializeAdvertisementResult_Tag v0_tag;
    np_ffi_DeserializedV0Advertisement v0;
  };
  struct {
    np_ffi_DeserializeAdvertisementResult_Tag v1_tag;
    np_ffi_DeserializedV1Advertisement v1;
  };
} np_ffi_DeserializeAdvertisementResult;

/**
 * A byte-string with a maximum size of N,
 * where only the first `len` bytes are considered
 * to contain the actual payload. N is only
 * permitted to be between 0 and 255.
 */
typedef struct {
  uint8_t len;
  uint8_t bytes[255];
} np_ffi_ByteBuffer_255;

/**
 * Represents the raw contents of the service payload data
 * under the Nearby Presence service UUID
 */
typedef struct {
  np_ffi_ByteBuffer_255 bytes;
} np_ffi_RawAdvertisementPayload;

/**
 * Representation of a transmission power,
 * as used for the Tx Power DE in V0 and V1.
 */
typedef struct {
  int8_t tx_power;
} np_ffi_TxPower;

/**
 * The bitfield data of a VOActions data element
 */
typedef struct {
  uint32_t bitfield;
} np_ffi_V0ActionBits;

/**
 * Representation of the Actions DE in V0.
 */
typedef enum {
  /**
   * A set of action bits which were present in a plaintext identity advertisement
   */
  NP_FFI_V0_ACTIONS_PLAINTEXT,
  /**
   * A set of action bits which were present in a encrypted identity advertisement
   */
  NP_FFI_V0_ACTIONS_ENCRYPTED,
} np_ffi_V0Actions_Tag;

typedef struct {
  np_ffi_V0Actions_Tag tag;
  union {
    struct {
      np_ffi_V0ActionBits plaintext;
    };
    struct {
      np_ffi_V0ActionBits encrypted;
    };
  };
} np_ffi_V0Actions;

/**
 * Representation of a V0 data element.
 */
typedef enum {
  NP_FFI_V0_DATA_ELEMENT_TX_POWER,
  NP_FFI_V0_DATA_ELEMENT_ACTIONS,
} np_ffi_V0DataElement_Tag;

typedef struct {
  np_ffi_V0DataElement_Tag tag;
  union {
    struct {
      np_ffi_TxPower tx_power;
    };
    struct {
      np_ffi_V0Actions actions;
    };
  };
} np_ffi_V0DataElement;

/**
 * The result of `V0Payload#get_de`.
 */
typedef enum {
  NP_FFI_GET_V0DE_RESULT_SUCCESS,
  NP_FFI_GET_V0DE_RESULT_ERROR,
} np_ffi_GetV0DEResult_Tag;

typedef struct {
  np_ffi_GetV0DEResult_Tag tag;
  union {
    struct {
      np_ffi_V0DataElement success;
    };
  };
} np_ffi_GetV0DEResult;

/**
 * Handle to a deserialized V1 section
 */
typedef struct {
  np_ffi_LegibleV1Sections legible_sections_handle;
  uint8_t legible_section_index;
  uint8_t num_des;
  np_ffi_DeserializedV1IdentityKind identity_tag;
} np_ffi_DeserializedV1Section;

/**
 * The result of attempting to get a particular V1 section
 * from its' index within the list of legible sections
 * via `DeserializedV1Advertisement::get_section`.
 */
typedef enum {
  NP_FFI_GET_V1_SECTION_RESULT_ERROR,
  NP_FFI_GET_V1_SECTION_RESULT_SUCCESS,
} np_ffi_GetV1SectionResult_Tag;

typedef struct {
  np_ffi_GetV1SectionResult_Tag tag;
  union {
    struct {
      np_ffi_DeserializedV1Section success;
    };
  };
} np_ffi_GetV1SectionResult;

/**
 * Representation of the data-element type tag
 * of a V1 data element.
 */
typedef struct {
  uint32_t code;
} np_ffi_V1DEType;

/**
 * A byte-string with a maximum size of N,
 * where only the first `len` bytes are considered
 * to contain the actual payload. N is only
 * permitted to be between 0 and 255.
 */
typedef struct {
  uint8_t len;
  uint8_t bytes[127];
} np_ffi_ByteBuffer_127;

/**
 * FFI-transmissible representation of a generic V1 data-element.
 * This representation is stable, and so you may directly
 * reference this struct's fields if you wish.
 */
typedef struct {
  /**
   * The offset of this generic data-element.
   */
  uint8_t offset;
  /**
   * The DE type code of this generic data-element.
   */
  np_ffi_V1DEType de_type;
  /**
   * The raw data-element byte payload, up to
   * 127 bytes in length.
   */
  np_ffi_ByteBuffer_127 payload;
} np_ffi_GenericV1DataElement;

/**
 * FFI-transmissible representation of a V1 data-element
 */
typedef enum {
  /**
   * A "generic" V1 data-element, for which we have no
   * particular information about its schema (just
   * a DE type code and a byte payload.)
   */
  NP_FFI_V1_DATA_ELEMENT_GENERIC,
} np_ffi_V1DataElement_Tag;

typedef struct {
  np_ffi_V1DataElement_Tag tag;
  union {
    struct {
      np_ffi_GenericV1DataElement generic;
    };
  };
} np_ffi_V1DataElement;

/**
 * Represents the result of the `DeserializedV1Section#get_de` operation.
 */
typedef enum {
  NP_FFI_GET_V1DE_RESULT_ERROR,
  NP_FFI_GET_V1DE_RESULT_SUCCESS,
} np_ffi_GetV1DEResult_Tag;

typedef struct {
  np_ffi_GetV1DEResult_Tag tag;
  union {
    struct {
      np_ffi_V1DataElement success;
    };
  };
} np_ffi_GetV1DEResult;

/**
 * Overrides the global panic handler to be used when NP C FFI calls panic.
 * This method will only have an effect on the global panic-handler
 * the first time it's called, and this method will return `true`
 * to indicate that the panic handler was successfully set.
 * All subsequent calls to this method
 * will simply ignore the argument and return `false`.
 *
 * If the passed function pointer is non-null,
 * then we will call it upon every panic,
 * followed by the default panicking behavior for
 * the platform (in the case where the user-specified
 * function does not terminate or hang the running process.)
 *
 * Otherwise, we will resort to the
 * default panicking behavior for the system, which
 * is a printed stack trace followed by an abort
 * when this crate is compiled with `std`,
 * but a bare `loop { }` when this crate is compiled without.
 */
bool np_ffi_global_config_panic_handler(void (*handler)(np_ffi_PanicReason));

/**
 * Sets an override to the number of shards to employ in the NP FFI's
 * internal handle-maps, which places an upper bound on the number
 * of writing threads which may make progress at any one time
 * when concurrently accessing handles of the same type.
 *
 * By default, this value will be set to 16, or in `std` environments,
 * the minimum of 16 and the number of available hardware threads.
 * A shard value override of zero will be interpreted the same
 * as this default.
 *
 * Setting this value will have no effect if the handle-maps for the
 * API have already begun being used by the client code, and any
 * values set will take effect upon the first usage of _any_ non-`np_ffi_global_config_set`
 * API call.
 */
void np_ffi_global_config_set_num_shards(uint8_t num_shards);

/**
 * Sets the maximum number of active handles to credential slabs
 * which may be active at any one time.
 * Default value: Max value.
 * Max value: `u32::MAX - 1`.
 *
 * Useful for bounding the maximum memory used by the client application
 * on credential slabs in constrained-memory environments.
 *
 * Setting this value will have no effect if the handle-maps for the
 * API have already begun being used by the client code, and any
 * values set will take effect upon the first usage of any API
 * call utilizing credential slabs.
 */
void np_ffi_global_config_set_max_num_credential_slabs(uint32_t max_num_credential_slabs);

/**
 * Sets the maximum number of active handles to credential books
 * which may be active at any one time.
 * Default value: Max value.
 * Max value: `u32::MAX - 1`.
 *
 * Useful for bounding the maximum memory used by the client application
 * on credential books in constrained-memory environments.
 *
 * Setting this value will have no effect if the handle-maps for the
 * API have already begun being used by the client code, and any
 * values set will take effect upon the first usage of any API
 * call utilizing credential books.
 */
void np_ffi_global_config_set_max_num_credential_books(uint32_t max_num_credential_books);

/**
 * Sets the maximum number of active handles to deserialized v0
 * advertisements which may be active at any one time.
 *
 * Useful for bounding the maximum memory used by the client application
 * on v0 advertisements in constrained-memory environments.
 *
 * Default value: Max value.
 * Max value: `u32::MAX - 1`.
 *
 * Setting this value will have no effect if the handle-maps for the
 * API have already begun being used by the client code, and any
 * values set will take effect upon the first usage of any API
 * call which references or returns a deserialized V0 advertisement.
 */
void np_ffi_global_config_set_max_num_deserialized_v0_advertisements(uint32_t max_num_deserialized_v0_advertisements);

/**
 * Sets the maximum number of active handles to deserialized v1
 * advertisements which may be active at any one time.
 *
 * Useful for bounding the maximum memory used by the client application
 * on v1 advertisements in constrained-memory environments.
 *
 * Default value: Max value.
 * Max value: `u32::MAX - 1`.
 *
 * Setting this value will have no effect if the handle-maps for the
 * API have already begun being used by the client code, and any
 * values set will take effect upon the first usage of any API
 * call which references or returns a deserialized V1 advertisement.
 */
void np_ffi_global_config_set_max_num_deserialized_v1_advertisements(uint32_t max_num_deserialized_v1_advertisements);

/**
 * Allocates a new credential-book from the given slab, returning a handle
 * to the created object. The slab will be deallocated by this call.
 */
np_ffi_CreateCredentialBookResult np_ffi_create_credential_book_from_slab(np_ffi_CredentialSlab slab);

/**
 * Gets the tag of a `CreateCredentialBookResult` tagged enum.
 */
np_ffi_CreateCredentialBookResultKind np_ffi_CreateCredentialBookResult_kind(np_ffi_CreateCredentialBookResult result);

/**
 * Casts a `CreateCredentialBookResult` to the `SUCCESS` variant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_CredentialBook np_ffi_CreateCredentialBookResult_into_SUCCESS(np_ffi_CreateCredentialBookResult result);

/**
 * Deallocates a credential-slab by its handle.
 */
np_ffi_DeallocateResult np_ffi_deallocate_credential_slab(np_ffi_CredentialSlab credential_slab);

/**
 * Deallocates a credential-book by its handle
 */
np_ffi_DeallocateResult np_ffi_deallocate_credential_book(np_ffi_CredentialBook credential_book);

/**
 * Allocates a new credential-slab, returning a handle to the created object
 */
np_ffi_CreateCredentialSlabResult np_ffi_create_credential_slab(void);

/**
 * Gets the tag of a `CreateCredentialSlabResult` tagged enum.
 */
np_ffi_CreateCredentialSlabResultKind np_ffi_CreateCredentialSlabResult_kind(np_ffi_CreateCredentialSlabResult result);

/**
 * Casts a `CreateCredentialSlabResult` to the `SUCCESS` variant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_CredentialSlab np_ffi_CreateCredentialSlabResult_into_SUCCESS(np_ffi_CreateCredentialSlabResult result);

/**
 * Adds the given V0 discovery credential with some associated
 * match-data to this credential slab.
 *
 * Safety: this is safe if the provided pointer points to a valid memory address
 * which contains the correct len amount of bytes. The copy from the memory address isn't atomic,
 * so concurrent modification of the array from another thread would cause undefined behavior.
 */
np_ffi_AddCredentialToSlabResult np_ffi_CredentialSlab_add_v0_credential(np_ffi_CredentialSlab credential_slab,
                                                                         np_ffi_V0MatchableCredential v0_cred);

/**
 * Adds the given V1 discovery credential with some associated
 * match-data to this credential slab.
 *
 * Safety: this is safe if the provided pointer points to a valid memory address
 * which contains the correct len amount of bytes. The copy from the memory address isn't atomic,
 * so concurrent modification of the array from another thread would cause undefined behavior.
 */
np_ffi_AddCredentialToSlabResult np_ffi_CredentialSlab_add_v1_credential(np_ffi_CredentialSlab credential_slab,
                                                                         np_ffi_V1MatchableCredential v1_cred);

/**
 * Attempts to deserialize an advertisement with the given service-data
 * payload (presumed to be under the NP service UUID) using credentials
 * pulled from the given credential-book.
 */
np_ffi_DeserializeAdvertisementResult np_ffi_deserialize_advertisement(np_ffi_RawAdvertisementPayload adv_payload,
                                                                       np_ffi_CredentialBook credential_book);

/**
 * Gets the tag of a `DeserializeAdvertisementResult` tagged-union.
 */
np_ffi_DeserializeAdvertisementResultKind np_ffi_DeserializeAdvertisementResult_kind(np_ffi_DeserializeAdvertisementResult result);

/**
 * Casts a `DeserializeAdvertisementResult` to the `V0` variant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_DeserializedV0Advertisement np_ffi_DeserializeAdvertisementResult_into_V0(np_ffi_DeserializeAdvertisementResult result);

/**
 * Casts a `DeserializeAdvertisementResult` to the `V1` variant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_DeserializedV1Advertisement np_ffi_DeserializeAdvertisementResult_into_V1(np_ffi_DeserializeAdvertisementResult result);

/**
 * Deallocates any internal data referenced by a `DeserializeAdvertisementResult`. This should only
 * be used if into_V0 or into_V1, have not been called yet as it shares the same underlying
 * resource.
 */
np_ffi_DeallocateResult np_ffi_deallocate_deserialize_advertisement_result(np_ffi_DeserializeAdvertisementResult result);

/**
 * Deallocates any internal data referenced by a `DeserializedV0Advertisement`
 */
np_ffi_DeallocateResult np_ffi_deallocate_deserialized_V0_advertisement(np_ffi_DeserializedV0Advertisement adv);

/**
 * Deallocates any internal data referenced by a `DeserializedV1Advertisement`
 */
np_ffi_DeallocateResult np_ffi_deallocate_deserialized_V1_advertisement(np_ffi_DeserializedV1Advertisement adv);

/**
 * Gets the tag of a `DeserializedV0Advertisement` tagged-union.
 */
np_ffi_DeserializedV0AdvertisementKind np_ffi_DeserializedV0Advertisement_kind(np_ffi_DeserializedV0Advertisement result);

/**
 * Casts a `DeserializedV0Advertisement` to the `Legible` variant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_LegibleDeserializedV0Advertisement np_ffi_DeserializedV0Advertisement_into_LEGIBLE(np_ffi_DeserializedV0Advertisement adv);

/**
 * Gets the number of DEs in a legible deserialized advertisement.
 * Suitable as an iteration bound for `V0Payload#get_de`.
 */
uint8_t np_ffi_LegibleDeserializedV0Advertisement_get_num_des(np_ffi_LegibleDeserializedV0Advertisement adv);

/**
 * Gets just the data-element payload of a `LegibleDeserializedV0Advertisement`.
 */
np_ffi_V0Payload np_ffi_LegibleDeserializedV0Advertisement_into_payload(np_ffi_LegibleDeserializedV0Advertisement adv);

/**
 * Gets just the identity kind associated with a `LegibleDeserializedV0Advertisement`.
 */
np_ffi_DeserializedV0IdentityKind np_ffi_LegibleDeserializedV0Advertisement_get_identity_kind(np_ffi_LegibleDeserializedV0Advertisement adv);

/**
 * Deallocates any internal data of a `LegibleDeserializedV0Advertisement`
 */
np_ffi_DeallocateResult np_ffi_deallocate_legible_v0_advertisement(np_ffi_LegibleDeserializedV0Advertisement adv);

/**
 * Attempts to get the data-element with the given index in the passed v0 adv payload
 */
np_ffi_GetV0DEResult np_ffi_V0Payload_get_de(np_ffi_V0Payload payload, uint8_t index);

/**
 * Deallocates any internal data of a `V0Payload`
 */
np_ffi_DeallocateResult np_ffi_deallocate_v0_payload(np_ffi_V0Payload payload);

/**
 * Gets the tag of a `GetV0DEResult` tagged-union.
 */
np_ffi_GetV0DEResultKind np_ffi_GetV0DEResult_kind(np_ffi_GetV0DEResult result);

/**
 * Casts a `GetV0DEResult` to the `Success` variant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_V0DataElement np_ffi_GetV0DEResult_into_SUCCESS(np_ffi_GetV0DEResult result);

/**
 * Gets the tag of a `V0DataElement` tagged-union.
 */
np_ffi_V0DataElementKind np_ffi_V0DataElement_kind(np_ffi_V0DataElement de);

/**
 * Casts a `V0DataElement` to the `TxPower` variant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_TxPower np_ffi_V0DataElement_into_TX_POWER(np_ffi_V0DataElement de);

/**
 * Casts a `V0DataElement` to the `Actions` variant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_V0Actions np_ffi_V0DataElement_into_ACTIONS(np_ffi_V0DataElement de);

/**
 * Return whether a boolean action type is set in this data element
 */
bool np_ffi_V0Actions_has_action(np_ffi_V0Actions actions, np_ffi_BooleanActionType action_type);

/**
 * Gets the 4 bit context sync sequence number as a u8 from this data element
 */
uint8_t np_ffi_V0Actions_get_context_sync_sequence_number(np_ffi_V0Actions actions);

/**
 * Return whether a boolean action type is set in this data element
 */
uint32_t np_ffi_V0Actions_as_u32(np_ffi_V0Actions actions);

/**
 * Gets the number of legible sections on a deserialized V1 advertisement.
 * Suitable as an index bound for the second argument of
 * `np_ffi_DeserializedV1Advertisement#get_section`.
 */
uint8_t np_ffi_DeserializedV1Advertisement_get_num_legible_sections(np_ffi_DeserializedV1Advertisement adv);

/**
 * Gets the number of sections on a deserialized V1 advertisement which
 * were unable to be decrypted with the credentials that the receiver possesses.
 */
uint8_t np_ffi_DeserializedV1Advertisement_get_num_undecryptable_sections(np_ffi_DeserializedV1Advertisement adv);

/**
 * Gets the legible section with the given index in a deserialized V1 advertisement.
 */
np_ffi_GetV1SectionResult np_ffi_DeserializedV1Advertisement_get_section(np_ffi_DeserializedV1Advertisement adv,
                                                                         uint8_t legible_section_index);

/**
 * Gets the tag of the `GetV1SectionResult` tagged-union.
 */
np_ffi_GetV1SectionResultKind np_ffi_GetV1SectionResult_kind(np_ffi_GetV1SectionResult result);

/**
 * Casts a `GetV1SectionResult` to the `Success` variant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_DeserializedV1Section np_ffi_GetV1SectionResult_into_SUCCESS(np_ffi_GetV1SectionResult result);

/**
 * Gets the number of data elements in a deserialized v1 section.
 * Suitable as an iteration bound for the second argument of
 * `np_ffi_DeserializedV1Section_get_de`.
 */
uint8_t np_ffi_DeserializedV1Section_get_num_des(np_ffi_DeserializedV1Section section);

/**
 * Gets the tag of the identity tagged-union used for the passed section.
 */
np_ffi_DeserializedV1IdentityKind np_ffi_DeserializedV1Section_get_identity_kind(np_ffi_DeserializedV1Section section);

/**
 * Gets the data-element with the given index in the passed section.
 */
np_ffi_GetV1DEResult np_ffi_DeserializedV1Section_get_de(np_ffi_DeserializedV1Section section,
                                                         uint8_t de_index);

/**
 * Gets the tag of the `GetV1DEResult` tagged-union.
 */
np_ffi_GetV1DEResultKind np_ffi_GetV1DEResult_kind(np_ffi_GetV1DEResult result);

/**
 * Casts a `GetV1DEResult` to the `Success` vartiant, panicking in the
 * case where the passed value is of a different enum variant.
 */
np_ffi_V1DataElement np_ffi_GetV1DEResult_into_SUCCESS(np_ffi_GetV1DEResult result);

/**
 * Converts a `V1DataElement` to a `GenericV1DataElement` which
 * only maintains information about the DE's type-code and payload.
 */
np_ffi_GenericV1DataElement np_ffi_V1DataElement_to_generic(np_ffi_V1DataElement de);

/**
 * Extracts the numerical value of the given V1 DE type code as
 * an unsigned 32-bit integer.
 */
uint32_t np_ffi_V1DEType_to_uint32_t(np_ffi_V1DEType de_type);
