/*
 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 <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>

namespace np_ffi {
namespace internal {

/// Result type for trying to add a credential to a credential-slab.
enum class AddCredentialToSlabResult : uint8_t {
  /// We succeeded in adding the credential to the slab.
  Success = 0,
  /// The handle to the slab was actually invalid.
  InvalidHandle = 1,
};

/// The possible boolean action types which can be present in an Actions data element
enum class BooleanActionType : uint8_t {
  ActiveUnlock = 8,
  NearbyShare = 9,
  InstantTethering = 10,
  PhoneHub = 11,
  PresenceManager = 12,
  Finder = 13,
  FastPairSass = 14,
};

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

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

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

/// Discriminant for `DeserializeAdvertisementResult`.
enum class DeserializeAdvertisementResultKind : uint8_t {
  /// Deserializing the advertisement failed, for some reason or another.
  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.
  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.
  V1 = 2,
};

/// Discriminant for possible results of V0 advertisement deserialization
enum class DeserializedV0AdvertisementKind : uint8_t {
  /// The deserialized V0 advertisement was legible.
  /// The associated payload may be obtained via
  /// `DeserializedV0Advertisement#into_legible`.
  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.
  NoMatchingCredentials = 1,
};

/// Discriminant for deserialized information about the V0
/// identity utilized by a deserialized V0 advertisement.
enum class DeserializedV0IdentityKind : uint8_t {
  /// The deserialized identity was a plaintext identity.
  Plaintext = 0,
  /// The deserialized identity was some decrypted identity.
  Decrypted = 1,
};

/// Discriminant for `DeserializedV1Identity`.
enum class DeserializedV1IdentityKind : uint8_t {
  /// The deserialized v1 identity was plaintext
  Plaintext = 0,
  /// The deserialized v1 identity corresponded
  /// to some kind of decrypted identity.
  Decrypted = 1,
};

/// Discriminant of `GetV0DEResult`.
enum class GetV0DEResultKind : uint8_t {
  /// The attempt to get the DE succeeded.
  /// The associated payload may be obtained via
  /// `GetV0DEResult#into_success`.
  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.
  Error = 1,
};

/// Discriminant for the `GetV1DEResult` enum.
enum class GetV1DEResultKind : uint8_t {
  /// 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.
  Error = 0,
  /// Attempting to get the DE at the given position succeeded.
  /// The underlying DE may be extracted with `GetV1DEResult#into_success`.
  Success = 1,
};

/// Discriminant for `GetV1SectionResult`
enum class GetV1SectionResultKind : uint8_t {
  /// 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.
  Error = 0,
  /// The attempt to get the section succeeded.
  /// The wrapped section may be obtained via
  /// `GetV1SectionResult#into_success`.
  Success = 1,
};

/// Structure for categorized reasons for why a NP C FFI call may
/// be panicking.
enum class PanicReason : uint8_t {
  /// 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.)
  EnumCastFailed = 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.
  AssertFailed = 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.
  InvalidActionBits = 2,
};

/// Discriminant for `V0DataElement`.
enum class V0DataElementKind : uint8_t {
  /// A transmission Power (Tx Power) data-element.
  /// The associated payload may be obtained via
  /// `V0DataElement#into_tx_power`.
  TxPower = 0,
  /// The Actions data-element.
  /// The associated payload may be obtained via
  /// `V0DataElement#into_actions`.
  Actions = 1,
};

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

/// Result type for `create_credential_book`
union CreateCredentialBookResult {
  enum class Tag : uint8_t {
    Success = 0,
    NoSpaceLeft = 1,
    InvalidSlabHandle = 2,
  };

  struct Success_Body {
    Tag tag;
    CredentialBook _0;
  };

  struct {
    Tag tag;
  };
  Success_Body success;
};

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

/// Result type for `create_credential_slab`
struct CreateCredentialSlabResult {
  enum class Tag {
    NoSpaceLeft,
    Success,
  };

  struct Success_Body {
    CredentialSlab _0;
  };

  Tag tag;
  union {
    Success_Body success;
  };
};

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

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

/// 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.
struct V0MatchableCredential {
  V0DiscoveryCredential discovery_cred;
  FfiMatchedCredential matched_cred;
};

/// Cryptographic information about a particular V1 discovery credential
/// necessary to match and decrypt encrypted V1 advertisement sections.
struct V1DiscoveryCredential {
  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];
};

/// 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.
struct V1MatchableCredential {
  V1DiscoveryCredential discovery_cred;
  FfiMatchedCredential matched_cred;
};

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

/// Represents a deserialized V0 advertisement whose DE contents may be read
struct LegibleDeserializedV0Advertisement {
  uint8_t num_des;
  V0Payload payload;
  DeserializedV0IdentityKind identity_kind;
};

/// Represents a deserialized V0 advertisement
struct DeserializedV0Advertisement {
  enum class Tag {
    Legible,
    NoMatchingCredentials,
  };

  struct Legible_Body {
    LegibleDeserializedV0Advertisement _0;
  };

  Tag tag;
  union {
    Legible_Body legible;
  };
};

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

/// Representation of a deserialized V1 advertisement
struct DeserializedV1Advertisement {
  uint8_t num_legible_sections;
  uint8_t num_undecryptable_sections;
  LegibleV1Sections legible_sections;
};

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

  struct V0_Body {
    Tag tag;
    DeserializedV0Advertisement _0;
  };

  struct V1_Body {
    Tag tag;
    DeserializedV1Advertisement _0;
  };

  struct {
    Tag tag;
  };
  V0_Body v0;
  V1_Body v1;
};

/// 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.
template<uintptr_t N>
struct ByteBuffer {
  uint8_t len;
  uint8_t bytes[N];
};

/// Represents the raw contents of the service payload data
/// under the Nearby Presence service UUID
struct RawAdvertisementPayload {
  ByteBuffer<255> bytes;
};

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

/// The bitfield data of a VOActions data element
struct V0ActionBits {
  uint32_t bitfield;
};

/// Representation of the Actions DE in V0.
struct V0Actions {
  enum class Tag {
    /// A set of action bits which were present in a plaintext identity advertisement
    Plaintext,
    /// A set of action bits which were present in a encrypted identity advertisement
    Encrypted,
  };

  struct Plaintext_Body {
    V0ActionBits _0;
  };

  struct Encrypted_Body {
    V0ActionBits _0;
  };

  Tag tag;
  union {
    Plaintext_Body plaintext;
    Encrypted_Body encrypted;
  };
};

/// Representation of a V0 data element.
struct V0DataElement {
  enum class Tag {
    TxPower,
    Actions,
  };

  struct TxPower_Body {
    TxPower _0;
  };

  struct Actions_Body {
    V0Actions _0;
  };

  Tag tag;
  union {
    TxPower_Body tx_power;
    Actions_Body actions;
  };
};

/// The result of `V0Payload#get_de`.
struct GetV0DEResult {
  enum class Tag {
    Success,
    Error,
  };

  struct Success_Body {
    V0DataElement _0;
  };

  Tag tag;
  union {
    Success_Body success;
  };
};

/// Handle to a deserialized V1 section
struct DeserializedV1Section {
  LegibleV1Sections legible_sections_handle;
  uint8_t legible_section_index;
  uint8_t num_des;
  DeserializedV1IdentityKind identity_tag;
};

/// The result of attempting to get a particular V1 section
/// from its' index within the list of legible sections
/// via `DeserializedV1Advertisement::get_section`.
struct GetV1SectionResult {
  enum class Tag {
    Error,
    Success,
  };

  struct Success_Body {
    DeserializedV1Section _0;
  };

  Tag tag;
  union {
    Success_Body success;
  };
};

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

/// 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.
struct GenericV1DataElement {
  /// The offset of this generic data-element.
  uint8_t offset;
  /// The DE type code of this generic data-element.
  V1DEType de_type;
  /// The raw data-element byte payload, up to
  /// 127 bytes in length.
  ByteBuffer<127> payload;
};

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

  struct Generic_Body {
    GenericV1DataElement _0;
  };

  Tag tag;
  union {
    Generic_Body generic;
  };
};

/// Represents the result of the `DeserializedV1Section#get_de` operation.
struct GetV1DEResult {
  enum class Tag {
    Error,
    Success,
  };

  struct Success_Body {
    V1DataElement _0;
  };

  Tag tag;
  union {
    Success_Body success;
  };
};

} // namespace internal
} // namespace np_ffi
