//--------------------------------------------------------------------------------------------------
// Copyright (c) id3 Technologies
// All Rights Reserved.
//--------------------------------------------------------------------------------------------------
// ignore_for_file: unused_import
import 'dart:convert';
import 'dart:ffi';
import 'dart:typed_data';
import 'package:ffi/ffi.dart';
import 'bioseal_sdk_generated_bindings.dart';
import 'bioseal_native.dart';

import '../id3_bioseal.dart';

final _finalizer = NativeFinalizer(biosealSDK.addresses.id3Bioseal_Dispose.cast());

/// Represents a BioSeal code.
class Bioseal implements Finalizable {
  /// Native handle.
  late Pointer<Pointer<id3Bioseal>> _pHandle;
  bool _disposable = true;
  static final _objectMap = {};

  /// Gets the native handle.
  /// return The native handle.
  Pointer<id3Bioseal> get handle => _pHandle.value;

  /// Creates a new instance of the Bioseal class.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Bioseal() {
    _pHandle = calloc();
    try {
      var err = biosealSDK.id3Bioseal_Initialize(_pHandle);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      _objectMap[_pHandle.value] = this;
      _finalizer.attach(this, _pHandle.cast(), detach: this);
    } finally {}
  }

  /// Creates a new instance of the Bioseal class.
  ///
  /// param handle     Handle to the Bioseal.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Bioseal.fromHandle(Pointer<id3Bioseal> handle) {
    _pHandle = calloc();
    _pHandle.value = handle;
    _disposable = false;
    _objectMap[_pHandle.value] = this;
  }

  /// Releases all resources used by this Bioseal.
  void dispose() {
    _objectMap.remove(_pHandle.value);
    if (_disposable) {
      biosealSDK.id3Bioseal_Dispose(_pHandle);
      calloc.free(_pHandle);
      _finalizer.detach(this);
    }
  }

  // externalResourceCallback
  late ResourceCallbackHandler _externalResourceCallbackApp;
  static int _externalResourceCallbackStatic(Pointer<Void> context, Pointer<id3BiosealResourceCallbackArgs> args) {
    var instance = _objectMap[context];
    return instance._externalResourceCallbackApp(instance, ResourceCallbackArgs.fromHandle(args));
  }

  // decryptionCallback
  late DecryptionCallbackHandler _decryptionCallbackApp;
  static int _decryptionCallbackStatic(Pointer<Void> context, Pointer<id3BiosealDecryptionArgs> args) {
    var instance = _objectMap[context];
    return instance._decryptionCallbackApp(instance, DecryptionArgs.fromHandle(args));
  }


  ///
  /// The BioSeal format without prefix information.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  BiosealFormat get format => getFormat();

  ///
  /// The BioSeal format with prefix information.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  BiosealFormat get extendedFormat => getExtendedFormat();

  ///
  /// The document issuing date.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  DateTime? get documentIssuingDate => getDocumentIssuingDate();

  ///
  /// The BioSeal signature date.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  DateTime? get signatureDate => getSignatureDate();

  ///
  /// The document type identification code. For AFNOR XP Z42-101 only.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String get documentType => getDocumentType();

  ///
  /// The identification code of the scope on which the document type is defined. For AFNOR XP Z42-101 only.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String get documentScope => getDocumentScope();

  ///
  /// The identifier of the country issuing the document. For AFNOR XP Z42-101 only.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String get documentIssuingCountry => getDocumentIssuingCountry();

  ///
  /// The manifest ID in ISO 22385 format.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  int get manifestId => getManifestId();

  ///
  /// The payload containing the data specific to the BioSeal.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Field get payload => getPayload();

  ///
  /// The manifest information.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Manifest get manifest => getManifest();

  ///
  /// Indicates whether the BioSeal contains images.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get containsImages => getContainsImages();

  ///
  /// Indicates whether the BioSeal contains portraits.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get containsPortraits => getContainsPortraits();

  ///
  /// Indicates whether the BioSeal contains biometric data.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get containsBiometrics => getContainsBiometrics();

  ///
  /// Indicates whether the BioSeal contains face templates.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get containsFaceTemplates => getContainsFaceTemplates();

  ///
  /// Indicates whether the BioSeal contains finger templates.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get containsFingerTemplates => getContainsFingerTemplates();

  ///
  /// Indicates whether the BioSeal contains extensions.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get containsExtensions => getContainsExtensions();

  ///
  /// The list of supported languages declared in the manifest.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  StringArray get supportedLanguages => getSupportedLanguages();

  ///
  /// The presentation view, in HTML format, created from the manifest and the data contained in the BioSeal.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String get htmlView => getHtmlView();

  ///
  /// The callback used to retrieve an external resource (LoTL, TSL, certificate, manifest, CRL) with specified URI.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  set externalResourceCallback(ResourceCallbackHandler value) => setExternalResourceCallback(value);

  ///
  /// The issuing reference of the certificate authority.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String get certificateAuthorityReference => getCertificateAuthorityReference();

  ///
  /// The identifier of the certificate.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String get certificateIdentifier => getCertificateIdentifier();

  ///
  /// The detailed certificate information.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  CertificateInformation get certificateInformation => getCertificateInformation();

  ///
  /// The BioSeal expiration date.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  DateTime? get expirationDate => getExpirationDate();

  ///
  /// Indicates whether the BioSeal contains auxiliary data.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get containsAuxData => getContainsAuxData();

  ///
  /// The auxiliary data containing additional information specific to the BioSeal.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Field get auxData => getAuxData();

  ///
  /// The list of biometric verification rules.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  BiometricVerificationRules get biometricVerificationRules => getBiometricVerificationRules();

  ///
  /// The log.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Log get log => getLog();

  ///
  /// The user authentication parameters.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  UserAuthentication get userAuthentication => getUserAuthentication();

  ///
  /// The header version.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  int get headerVersion => getHeaderVersion();

  ///
  /// The callback used to decrypt a field.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  set decryptionCallback(DecryptionCallbackHandler value) => setDecryptionCallback(value);

  ///
  /// Indicates whether the governance certification chain is verified.
  /// Hint: Default value is true.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get verifiesGovernance => getVerifiesGovernance();
  set verifiesGovernance(bool value) => setVerifiesGovernance(value);

  ///
  /// Indicates whether the VDS signature is verified.
  /// Hint: Default value is true.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get verifiesSignature => getVerifiesSignature();
  set verifiesSignature(bool value) => setVerifiesSignature(value);

  ///
  /// Indicates whether the verification process should verify the next CRL update.
  /// Hint: Default value is true.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get verifiesCrlUpdates => getVerifiesCrlUpdates();
  set verifiesCrlUpdates(bool value) => setVerifiesCrlUpdates(value);

  ///
  /// The last verification result.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  VerificationResult get verificationResult => getVerificationResult();

  ///
  /// The URL to the LoTL (List of Trust List).
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String? get lotlUrl => getLotlUrl();
  set lotlUrl(String? value) => setLotlUrl(value);

  ///
  /// The URL to the TSL (Trust Service List).
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String? get tslUrl => getTslUrl();
  set tslUrl(String? value) => setTslUrl(value);

  ///
  /// The URL to the manifest.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String get manifestUrl => getManifestUrl();
  set manifestUrl(String value) => setManifestUrl(value);

  ///
  /// The Issuing Agency Code (IAC). For ISO 22376:2023 format only.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String? get issuingAgencyCode => getIssuingAgencyCode();

  ///
  /// Prefix is present.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool get hasPrefix => getHasPrefix();

  ///
  /// The prefix.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String? get prefix => getPrefix();

  ///
  /// The data of the VDS as a binary array.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Uint8List get data => getData();

  // Public methods
  /// Gets the the BioSeal format without prefix information.
  ///
  /// return The BioSeal format without prefix information.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  BiosealFormat getFormat() {
    Pointer<Int32> pFormat = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetFormat(_pHandle.value, pFormat);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vFormat = BiosealFormatX.fromValue(pFormat.value);
      return vFormat;
    } finally {
      calloc.free(pFormat);
    }
  }

  /// Gets the the BioSeal format with prefix information.
  ///
  /// return The BioSeal format with prefix information.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  BiosealFormat getExtendedFormat() {
    Pointer<Int32> pExtendedFormat = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetExtendedFormat(_pHandle.value, pExtendedFormat);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vExtendedFormat = BiosealFormatX.fromValue(pExtendedFormat.value);
      return vExtendedFormat;
    } finally {
      calloc.free(pExtendedFormat);
    }
  }

  /// Gets the the document issuing date.
  ///
  /// return The document issuing date.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  DateTime? getDocumentIssuingDate() {
    DateTime documentIssuingDate = DateTime();
    var err = biosealSDK.id3Bioseal_GetDocumentIssuingDate(_pHandle.value, documentIssuingDate.handle);
    if (err == BiosealError.objectDoesNotExist.value) {
      documentIssuingDate.dispose();
      return null;
    }
    if (err != BiosealError.success.value) {
      documentIssuingDate.dispose();
      throw BiosealException(err);
    }
    return documentIssuingDate;
  }

  /// Gets the the BioSeal signature date.
  ///
  /// return The BioSeal signature date.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  DateTime? getSignatureDate() {
    DateTime signatureDate = DateTime();
    var err = biosealSDK.id3Bioseal_GetSignatureDate(_pHandle.value, signatureDate.handle);
    if (err == BiosealError.objectDoesNotExist.value) {
      signatureDate.dispose();
      return null;
    }
    if (err != BiosealError.success.value) {
      signatureDate.dispose();
      throw BiosealException(err);
    }
    return signatureDate;
  }

  /// Gets the the document type identification code. For AFNOR XP Z42-101 only.
  ///
  /// return The document type identification code. For AFNOR XP Z42-101 only.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getDocumentType() {
    Pointer<Char> pDocumentType = nullptr;
    Pointer<Int> pDocumentTypeSize = calloc.allocate(1);
    pDocumentTypeSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetDocumentType(_pHandle.value, pDocumentType, pDocumentTypeSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pDocumentType = calloc.allocate(pDocumentTypeSize.value);
        err = biosealSDK.id3Bioseal_GetDocumentType(_pHandle.value, pDocumentType, pDocumentTypeSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vDocumentType = utf8.decode(Uint8List.fromList(pDocumentType.cast<Uint8>().asTypedList(pDocumentTypeSize.value)));
      return vDocumentType;
    } finally {
      calloc.free(pDocumentType);
      calloc.free(pDocumentTypeSize);
    }
  }

  /// Gets the the identification code of the scope on which the document type is defined. For AFNOR XP Z42-101 only.
  ///
  /// return The identification code of the scope on which the document type is defined. For AFNOR XP Z42-101 only.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getDocumentScope() {
    Pointer<Char> pDocumentScope = nullptr;
    Pointer<Int> pDocumentScopeSize = calloc.allocate(1);
    pDocumentScopeSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetDocumentScope(_pHandle.value, pDocumentScope, pDocumentScopeSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pDocumentScope = calloc.allocate(pDocumentScopeSize.value);
        err = biosealSDK.id3Bioseal_GetDocumentScope(_pHandle.value, pDocumentScope, pDocumentScopeSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vDocumentScope = utf8.decode(Uint8List.fromList(pDocumentScope.cast<Uint8>().asTypedList(pDocumentScopeSize.value)));
      return vDocumentScope;
    } finally {
      calloc.free(pDocumentScope);
      calloc.free(pDocumentScopeSize);
    }
  }

  /// Gets the the identifier of the country issuing the document. For AFNOR XP Z42-101 only.
  ///
  /// return The identifier of the country issuing the document. For AFNOR XP Z42-101 only.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getDocumentIssuingCountry() {
    Pointer<Char> pDocumentIssuingCountry = nullptr;
    Pointer<Int> pDocumentIssuingCountrySize = calloc.allocate(1);
    pDocumentIssuingCountrySize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetDocumentIssuingCountry(_pHandle.value, pDocumentIssuingCountry, pDocumentIssuingCountrySize);
      if (err == BiosealError.insufficientBuffer.value) {
        pDocumentIssuingCountry = calloc.allocate(pDocumentIssuingCountrySize.value);
        err = biosealSDK.id3Bioseal_GetDocumentIssuingCountry(_pHandle.value, pDocumentIssuingCountry, pDocumentIssuingCountrySize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vDocumentIssuingCountry = utf8.decode(Uint8List.fromList(pDocumentIssuingCountry.cast<Uint8>().asTypedList(pDocumentIssuingCountrySize.value)));
      return vDocumentIssuingCountry;
    } finally {
      calloc.free(pDocumentIssuingCountry);
      calloc.free(pDocumentIssuingCountrySize);
    }
  }

  /// Gets the the manifest ID in ISO 22385 format.
  ///
  /// return The manifest ID in ISO 22385 format.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  int getManifestId() {
    Pointer<Int> pManifestId = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetManifestId(_pHandle.value, pManifestId);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vManifestId = pManifestId.value;
      return vManifestId;
    } finally {
      calloc.free(pManifestId);
    }
  }

  /// Gets the the payload containing the data specific to the BioSeal.
  ///
  /// return The payload containing the data specific to the BioSeal.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Field getPayload() {
    Field payload = Field();
    var err = biosealSDK.id3Bioseal_GetPayload(_pHandle.value, payload.handle);
    if (err != BiosealError.success.value) {
      payload.dispose();
      throw BiosealException(err);
    }
    return payload;
  }

  /// Gets the the manifest information.
  ///
  /// return The manifest information.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Manifest getManifest() {
    Manifest manifest = Manifest();
    var err = biosealSDK.id3Bioseal_GetManifest(_pHandle.value, manifest.handle);
    if (err != BiosealError.success.value) {
      manifest.dispose();
      throw BiosealException(err);
    }
    return manifest;
  }

  /// Gets the indicates whether the BioSeal contains images.
  ///
  /// return Indicates whether the BioSeal contains images.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getContainsImages() {
    Pointer<Bool> pContainsImages = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetContainsImages(_pHandle.value, pContainsImages);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vContainsImages = pContainsImages.value;
      return vContainsImages;
    } finally {
      calloc.free(pContainsImages);
    }
  }

  /// Gets the indicates whether the BioSeal contains portraits.
  ///
  /// return Indicates whether the BioSeal contains portraits.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getContainsPortraits() {
    Pointer<Bool> pContainsPortraits = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetContainsPortraits(_pHandle.value, pContainsPortraits);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vContainsPortraits = pContainsPortraits.value;
      return vContainsPortraits;
    } finally {
      calloc.free(pContainsPortraits);
    }
  }

  /// Gets the indicates whether the BioSeal contains biometric data.
  ///
  /// return Indicates whether the BioSeal contains biometric data.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getContainsBiometrics() {
    Pointer<Bool> pContainsBiometrics = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetContainsBiometrics(_pHandle.value, pContainsBiometrics);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vContainsBiometrics = pContainsBiometrics.value;
      return vContainsBiometrics;
    } finally {
      calloc.free(pContainsBiometrics);
    }
  }

  /// Gets the indicates whether the BioSeal contains face templates.
  ///
  /// return Indicates whether the BioSeal contains face templates.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getContainsFaceTemplates() {
    Pointer<Bool> pContainsFaceTemplates = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetContainsFaceTemplates(_pHandle.value, pContainsFaceTemplates);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vContainsFaceTemplates = pContainsFaceTemplates.value;
      return vContainsFaceTemplates;
    } finally {
      calloc.free(pContainsFaceTemplates);
    }
  }

  /// Gets the indicates whether the BioSeal contains finger templates.
  ///
  /// return Indicates whether the BioSeal contains finger templates.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getContainsFingerTemplates() {
    Pointer<Bool> pContainsFingerTemplates = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetContainsFingerTemplates(_pHandle.value, pContainsFingerTemplates);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vContainsFingerTemplates = pContainsFingerTemplates.value;
      return vContainsFingerTemplates;
    } finally {
      calloc.free(pContainsFingerTemplates);
    }
  }

  /// Gets the indicates whether the BioSeal contains extensions.
  ///
  /// return Indicates whether the BioSeal contains extensions.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getContainsExtensions() {
    Pointer<Bool> pContainsExtensions = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetContainsExtensions(_pHandle.value, pContainsExtensions);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vContainsExtensions = pContainsExtensions.value;
      return vContainsExtensions;
    } finally {
      calloc.free(pContainsExtensions);
    }
  }

  /// Gets the the list of supported languages declared in the manifest.
  ///
  /// return The list of supported languages declared in the manifest.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  StringArray getSupportedLanguages() {
    StringArray supportedLanguages = StringArray();
    var err = biosealSDK.id3Bioseal_GetSupportedLanguages(_pHandle.value, supportedLanguages.handle);
    if (err != BiosealError.success.value) {
      supportedLanguages.dispose();
      throw BiosealException(err);
    }
    return supportedLanguages;
  }

  /// Gets the the presentation view, in HTML format, created from the manifest and the data contained in the BioSeal.
  ///
  /// return The presentation view, in HTML format, created from the manifest and the data contained in the BioSeal.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getHtmlView() {
    Pointer<Char> pHtmlView = nullptr;
    Pointer<Int> pHtmlViewSize = calloc.allocate(1);
    pHtmlViewSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetHtmlView(_pHandle.value, pHtmlView, pHtmlViewSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pHtmlView = calloc.allocate(pHtmlViewSize.value);
        err = biosealSDK.id3Bioseal_GetHtmlView(_pHandle.value, pHtmlView, pHtmlViewSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vHtmlView = utf8.decode(Uint8List.fromList(pHtmlView.cast<Uint8>().asTypedList(pHtmlViewSize.value)));
      return vHtmlView;
    } finally {
      calloc.free(pHtmlView);
      calloc.free(pHtmlViewSize);
    }
  }

  /// Sets the the callback used to retrieve an external resource (LoTL, TSL, certificate, manifest, CRL) with specified URI.
  ///
  /// param externalResourceCallback The callback used to retrieve an external resource (LoTL, TSL, certificate, manifest, CRL) with specified URI.
  /// param context The callback context.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void setExternalResourceCallback(ResourceCallbackHandler externalResourceCallback) {
    const except = -8003;
    _externalResourceCallbackApp = externalResourceCallback;
    var err = biosealSDK.id3Bioseal_SetExternalResourceCallback(_pHandle.value, Pointer.fromFunction<ResourceCallbackHandlerNative>(_externalResourceCallbackStatic, except), _pHandle.value.cast());
    if (err != BiosealError.success.value) {
      throw BiosealException(err);
    }
  }

  /// Gets the the issuing reference of the certificate authority.
  ///
  /// return The issuing reference of the certificate authority.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getCertificateAuthorityReference() {
    Pointer<Char> pCertificateAuthorityReference = nullptr;
    Pointer<Int> pCertificateAuthorityReferenceSize = calloc.allocate(1);
    pCertificateAuthorityReferenceSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetCertificateAuthorityReference(_pHandle.value, pCertificateAuthorityReference, pCertificateAuthorityReferenceSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pCertificateAuthorityReference = calloc.allocate(pCertificateAuthorityReferenceSize.value);
        err = biosealSDK.id3Bioseal_GetCertificateAuthorityReference(_pHandle.value, pCertificateAuthorityReference, pCertificateAuthorityReferenceSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vCertificateAuthorityReference = utf8.decode(Uint8List.fromList(pCertificateAuthorityReference.cast<Uint8>().asTypedList(pCertificateAuthorityReferenceSize.value)));
      return vCertificateAuthorityReference;
    } finally {
      calloc.free(pCertificateAuthorityReference);
      calloc.free(pCertificateAuthorityReferenceSize);
    }
  }

  /// Gets the the identifier of the certificate.
  ///
  /// return The identifier of the certificate.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getCertificateIdentifier() {
    Pointer<Char> pCertificateIdentifier = nullptr;
    Pointer<Int> pCertificateIdentifierSize = calloc.allocate(1);
    pCertificateIdentifierSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetCertificateIdentifier(_pHandle.value, pCertificateIdentifier, pCertificateIdentifierSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pCertificateIdentifier = calloc.allocate(pCertificateIdentifierSize.value);
        err = biosealSDK.id3Bioseal_GetCertificateIdentifier(_pHandle.value, pCertificateIdentifier, pCertificateIdentifierSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vCertificateIdentifier = utf8.decode(Uint8List.fromList(pCertificateIdentifier.cast<Uint8>().asTypedList(pCertificateIdentifierSize.value)));
      return vCertificateIdentifier;
    } finally {
      calloc.free(pCertificateIdentifier);
      calloc.free(pCertificateIdentifierSize);
    }
  }

  /// Gets the the detailed certificate information.
  ///
  /// return The detailed certificate information.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  CertificateInformation getCertificateInformation() {
    CertificateInformation certificateInformation = CertificateInformation();
    var err = biosealSDK.id3Bioseal_GetCertificateInformation(_pHandle.value, certificateInformation.handle);
    if (err != BiosealError.success.value) {
      certificateInformation.dispose();
      throw BiosealException(err);
    }
    return certificateInformation;
  }

  /// Gets the the BioSeal expiration date.
  ///
  /// return The BioSeal expiration date.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  DateTime? getExpirationDate() {
    DateTime expirationDate = DateTime();
    var err = biosealSDK.id3Bioseal_GetExpirationDate(_pHandle.value, expirationDate.handle);
    if (err == BiosealError.objectDoesNotExist.value) {
      expirationDate.dispose();
      return null;
    }
    if (err != BiosealError.success.value) {
      expirationDate.dispose();
      throw BiosealException(err);
    }
    return expirationDate;
  }

  /// Gets the indicates whether the BioSeal contains auxiliary data.
  ///
  /// return Indicates whether the BioSeal contains auxiliary data.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getContainsAuxData() {
    Pointer<Bool> pContainsAuxData = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetContainsAuxData(_pHandle.value, pContainsAuxData);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vContainsAuxData = pContainsAuxData.value;
      return vContainsAuxData;
    } finally {
      calloc.free(pContainsAuxData);
    }
  }

  /// Gets the the auxiliary data containing additional information specific to the BioSeal.
  ///
  /// return The auxiliary data containing additional information specific to the BioSeal.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Field getAuxData() {
    Field auxData = Field();
    var err = biosealSDK.id3Bioseal_GetAuxData(_pHandle.value, auxData.handle);
    if (err != BiosealError.success.value) {
      auxData.dispose();
      throw BiosealException(err);
    }
    return auxData;
  }

  /// Gets the the list of biometric verification rules.
  ///
  /// return The list of biometric verification rules.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  BiometricVerificationRules getBiometricVerificationRules() {
    BiometricVerificationRules biometricVerificationRules = BiometricVerificationRules();
    var err = biosealSDK.id3Bioseal_GetBiometricVerificationRules(_pHandle.value, biometricVerificationRules.handle);
    if (err != BiosealError.success.value) {
      biometricVerificationRules.dispose();
      throw BiosealException(err);
    }
    return biometricVerificationRules;
  }

  /// Gets the the log.
  ///
  /// return The log.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Log getLog() {
    Log log = Log();
    var err = biosealSDK.id3Bioseal_GetLog(_pHandle.value, log.handle);
    if (err != BiosealError.success.value) {
      log.dispose();
      throw BiosealException(err);
    }
    return log;
  }

  /// Gets the the user authentication parameters.
  ///
  /// return The user authentication parameters.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  UserAuthentication getUserAuthentication() {
    UserAuthentication userAuthentication = UserAuthentication();
    var err = biosealSDK.id3Bioseal_GetUserAuthentication(_pHandle.value, userAuthentication.handle);
    if (err != BiosealError.success.value) {
      userAuthentication.dispose();
      throw BiosealException(err);
    }
    return userAuthentication;
  }

  /// Gets the the header version.
  ///
  /// return The header version.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  int getHeaderVersion() {
    Pointer<Int> pHeaderVersion = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetHeaderVersion(_pHandle.value, pHeaderVersion);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vHeaderVersion = pHeaderVersion.value;
      return vHeaderVersion;
    } finally {
      calloc.free(pHeaderVersion);
    }
  }

  /// Sets the the callback used to decrypt a field.
  ///
  /// param decryptionCallback The callback used to decrypt a field.
  /// param context The callback context.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void setDecryptionCallback(DecryptionCallbackHandler decryptionCallback) {
    const except = -8003;
    _decryptionCallbackApp = decryptionCallback;
    var err = biosealSDK.id3Bioseal_SetDecryptionCallback(_pHandle.value, Pointer.fromFunction<DecryptionCallbackHandlerNative>(_decryptionCallbackStatic, except), _pHandle.value.cast());
    if (err != BiosealError.success.value) {
      throw BiosealException(err);
    }
  }

  /// Gets the indicates whether the governance certification chain is verified.
  /// Hint: Default value is true.
  ///
  /// return Indicates whether the governance certification chain is verified.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getVerifiesGovernance() {
    Pointer<Bool> pVerifiesGovernance = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetVerifiesGovernance(_pHandle.value, pVerifiesGovernance);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vVerifiesGovernance = pVerifiesGovernance.value;
      return vVerifiesGovernance;
    } finally {
      calloc.free(pVerifiesGovernance);
    }
  }

  /// Sets the indicates whether the governance certification chain is verified.
  /// Hint: Default value is true.
  ///
  /// param verifiesGovernance Indicates whether the governance certification chain is verified.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void setVerifiesGovernance(bool verifiesGovernance) {
    var err = biosealSDK.id3Bioseal_SetVerifiesGovernance(_pHandle.value, verifiesGovernance);
    if (err != BiosealError.success.value) {
      throw BiosealException(err);
    }
  }

  /// Gets the indicates whether the VDS signature is verified.
  /// Hint: Default value is true.
  ///
  /// return Indicates whether the VDS signature is verified.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getVerifiesSignature() {
    Pointer<Bool> pVerifiesSignature = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetVerifiesSignature(_pHandle.value, pVerifiesSignature);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vVerifiesSignature = pVerifiesSignature.value;
      return vVerifiesSignature;
    } finally {
      calloc.free(pVerifiesSignature);
    }
  }

  /// Sets the indicates whether the VDS signature is verified.
  /// Hint: Default value is true.
  ///
  /// param verifiesSignature Indicates whether the VDS signature is verified.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void setVerifiesSignature(bool verifiesSignature) {
    var err = biosealSDK.id3Bioseal_SetVerifiesSignature(_pHandle.value, verifiesSignature);
    if (err != BiosealError.success.value) {
      throw BiosealException(err);
    }
  }

  /// Gets the indicates whether the verification process should verify the next CRL update.
  /// Hint: Default value is true.
  ///
  /// return Indicates whether the verification process should verify the next CRL update.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getVerifiesCrlUpdates() {
    Pointer<Bool> pVerifiesCrlUpdates = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetVerifiesCrlUpdates(_pHandle.value, pVerifiesCrlUpdates);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vVerifiesCrlUpdates = pVerifiesCrlUpdates.value;
      return vVerifiesCrlUpdates;
    } finally {
      calloc.free(pVerifiesCrlUpdates);
    }
  }

  /// Sets the indicates whether the verification process should verify the next CRL update.
  /// Hint: Default value is true.
  ///
  /// param verifiesCrlUpdates Indicates whether the verification process should verify the next CRL update.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void setVerifiesCrlUpdates(bool verifiesCrlUpdates) {
    var err = biosealSDK.id3Bioseal_SetVerifiesCrlUpdates(_pHandle.value, verifiesCrlUpdates);
    if (err != BiosealError.success.value) {
      throw BiosealException(err);
    }
  }

  /// Gets the the last verification result.
  ///
  /// return The last verification result.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  VerificationResult getVerificationResult() {
    Pointer<id3BiosealVerificationResult> pVerificationResult = calloc();
    var err = biosealSDK.id3Bioseal_GetVerificationResult(_pHandle.value, pVerificationResult);
    if (err != BiosealError.success.value) {
    	calloc.free(pVerificationResult);
    	throw BiosealException(err);
    }
    return VerificationResult(pVerificationResult);
  }

  /// Gets the the URL to the LoTL (List of Trust List).
  ///
  /// return The URL to the LoTL (List of Trust List).
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String? getLotlUrl() {
    Pointer<Char> pLotlUrl = nullptr;
    Pointer<Int> pLotlUrlSize = calloc.allocate(1);
    pLotlUrlSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetLotlUrl(_pHandle.value, pLotlUrl, pLotlUrlSize);
      if (err == BiosealError.objectDoesNotExist.value) {
        return null;
      }
      if (err == BiosealError.insufficientBuffer.value) {
        pLotlUrl = calloc.allocate(pLotlUrlSize.value);
        err = biosealSDK.id3Bioseal_GetLotlUrl(_pHandle.value, pLotlUrl, pLotlUrlSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vLotlUrl = utf8.decode(Uint8List.fromList(pLotlUrl.cast<Uint8>().asTypedList(pLotlUrlSize.value)));
      return vLotlUrl;
    } finally {
      calloc.free(pLotlUrl);
      calloc.free(pLotlUrlSize);
    }
  }

  /// Sets the the URL to the LoTL (List of Trust List).
  ///
  /// param lotlUrl The URL to the LoTL (List of Trust List).
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void setLotlUrl(String? lotlUrl) {
    Pointer<Char>? pLotlUrl = lotlUrl?.toNativeUtf8().cast<Char>();
    try {
      var err = biosealSDK.id3Bioseal_SetLotlUrl(_pHandle.value, pLotlUrl ?? nullptr);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
    } finally {
      if (pLotlUrl != null) {
        calloc.free(pLotlUrl);
      }
    }
  }

  /// Gets the the URL to the TSL (Trust Service List).
  ///
  /// return The URL to the TSL (Trust Service List).
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String? getTslUrl() {
    Pointer<Char> pTslUrl = nullptr;
    Pointer<Int> pTslUrlSize = calloc.allocate(1);
    pTslUrlSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetTslUrl(_pHandle.value, pTslUrl, pTslUrlSize);
      if (err == BiosealError.objectDoesNotExist.value) {
        return null;
      }
      if (err == BiosealError.insufficientBuffer.value) {
        pTslUrl = calloc.allocate(pTslUrlSize.value);
        err = biosealSDK.id3Bioseal_GetTslUrl(_pHandle.value, pTslUrl, pTslUrlSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vTslUrl = utf8.decode(Uint8List.fromList(pTslUrl.cast<Uint8>().asTypedList(pTslUrlSize.value)));
      return vTslUrl;
    } finally {
      calloc.free(pTslUrl);
      calloc.free(pTslUrlSize);
    }
  }

  /// Sets the the URL to the TSL (Trust Service List).
  ///
  /// param tslUrl The URL to the TSL (Trust Service List).
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void setTslUrl(String? tslUrl) {
    Pointer<Char>? pTslUrl = tslUrl?.toNativeUtf8().cast<Char>();
    try {
      var err = biosealSDK.id3Bioseal_SetTslUrl(_pHandle.value, pTslUrl ?? nullptr);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
    } finally {
      if (pTslUrl != null) {
        calloc.free(pTslUrl);
      }
    }
  }

  /// Gets the the URL to the manifest.
  ///
  /// return The URL to the manifest.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getManifestUrl() {
    Pointer<Char> pManifestUrl = nullptr;
    Pointer<Int> pManifestUrlSize = calloc.allocate(1);
    pManifestUrlSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetManifestUrl(_pHandle.value, pManifestUrl, pManifestUrlSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pManifestUrl = calloc.allocate(pManifestUrlSize.value);
        err = biosealSDK.id3Bioseal_GetManifestUrl(_pHandle.value, pManifestUrl, pManifestUrlSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vManifestUrl = utf8.decode(Uint8List.fromList(pManifestUrl.cast<Uint8>().asTypedList(pManifestUrlSize.value)));
      return vManifestUrl;
    } finally {
      calloc.free(pManifestUrl);
      calloc.free(pManifestUrlSize);
    }
  }

  /// Sets the the URL to the manifest.
  ///
  /// param manifestUrl The URL to the manifest.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void setManifestUrl(String? manifestUrl) {
    Pointer<Char>? pManifestUrl = manifestUrl?.toNativeUtf8().cast<Char>();
    try {
      var err = biosealSDK.id3Bioseal_SetManifestUrl(_pHandle.value, pManifestUrl ?? nullptr);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
    } finally {
      if (pManifestUrl != null) {
        calloc.free(pManifestUrl);
      }
    }
  }

  /// Gets the the Issuing Agency Code (IAC). For ISO 22376:2023 format only.
  ///
  /// return The Issuing Agency Code (IAC). For ISO 22376:2023 format only.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String? getIssuingAgencyCode() {
    Pointer<Char> pIssuingAgencyCode = nullptr;
    Pointer<Int> pIssuingAgencyCodeSize = calloc.allocate(1);
    pIssuingAgencyCodeSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetIssuingAgencyCode(_pHandle.value, pIssuingAgencyCode, pIssuingAgencyCodeSize);
      if (err == BiosealError.objectDoesNotExist.value) {
        return null;
      }
      if (err == BiosealError.insufficientBuffer.value) {
        pIssuingAgencyCode = calloc.allocate(pIssuingAgencyCodeSize.value);
        err = biosealSDK.id3Bioseal_GetIssuingAgencyCode(_pHandle.value, pIssuingAgencyCode, pIssuingAgencyCodeSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vIssuingAgencyCode = utf8.decode(Uint8List.fromList(pIssuingAgencyCode.cast<Uint8>().asTypedList(pIssuingAgencyCodeSize.value)));
      return vIssuingAgencyCode;
    } finally {
      calloc.free(pIssuingAgencyCode);
      calloc.free(pIssuingAgencyCodeSize);
    }
  }

  /// Gets the prefix is present.
  ///
  /// return Prefix is present.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  bool getHasPrefix() {
    Pointer<Bool> pHasPrefix = calloc();
    try {
      var err = biosealSDK.id3Bioseal_GetHasPrefix(_pHandle.value, pHasPrefix);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vHasPrefix = pHasPrefix.value;
      return vHasPrefix;
    } finally {
      calloc.free(pHasPrefix);
    }
  }

  /// Gets the the prefix.
  ///
  /// return The prefix.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String? getPrefix() {
    Pointer<Char> pPrefix = nullptr;
    Pointer<Int> pPrefixSize = calloc.allocate(1);
    pPrefixSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetPrefix(_pHandle.value, pPrefix, pPrefixSize);
      if (err == BiosealError.objectDoesNotExist.value) {
        return null;
      }
      if (err == BiosealError.insufficientBuffer.value) {
        pPrefix = calloc.allocate(pPrefixSize.value);
        err = biosealSDK.id3Bioseal_GetPrefix(_pHandle.value, pPrefix, pPrefixSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vPrefix = utf8.decode(Uint8List.fromList(pPrefix.cast<Uint8>().asTypedList(pPrefixSize.value)));
      return vPrefix;
    } finally {
      calloc.free(pPrefix);
      calloc.free(pPrefixSize);
    }
  }

  /// Gets the the data of the VDS as a binary array.
  ///
  /// return The data of the VDS as a binary array.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  Uint8List getData() {
    Pointer<UnsignedChar> pData = nullptr;
    Pointer<Int> pDataSize = calloc();
    pDataSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetData(_pHandle.value, pData, pDataSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pData = calloc.allocate(pDataSize.value);
        err = biosealSDK.id3Bioseal_GetData(_pHandle.value, pData, pDataSize);
      }
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vData = Uint8List.fromList(pData.cast<Uint8>().asTypedList(pDataSize.value));
      return vData;
    } finally {
      calloc.free(pData);
      calloc.free(pDataSize);
    }
  }

  /// Clears all internal data.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void clear() {
    var err = biosealSDK.id3Bioseal_Clear(_pHandle.value);
    if (err != BiosealError.success.value) {
      throw BiosealException(err);
    }
  }

  /// Decodes and verifies the specified data buffer.
  ///
  /// param data The data buffer containing the BioSeal code.
  /// return Receives the verification results.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  VerificationResult verifyFromBuffer(Uint8List? data) {
    Pointer<UnsignedChar>? pData;
    if (data != null) {
    	pData = calloc.allocate<UnsignedChar>(data.length);
    	pData.cast<Uint8>().asTypedList(data.length).setAll(0, data);
    }
    Pointer<id3BiosealVerificationResult> pResult = calloc();
    try {
      var err = biosealSDK.id3Bioseal_VerifyFromBuffer(_pHandle.value, pData ?? nullptr, data?.length ?? 0, pResult);
      if (err != BiosealError.success.value) {
        calloc.free(pResult);
        throw BiosealException(err);
      }
      return VerificationResult(pResult);
    } finally {
      if (pData != null) {
        calloc.free(pData);
      }
    }
  }

  /// Decodes and verifies the specified string buffer.
  ///
  /// param data The string buffer containing the BioSeal code.
  /// return Receives the verification results.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  VerificationResult verifyFromString(String? data) {
    Pointer<Char>? pData = data?.toNativeUtf8().cast<Char>();
    Pointer<id3BiosealVerificationResult> pResult = calloc();
    try {
      var err = biosealSDK.id3Bioseal_VerifyFromString(_pHandle.value, pData ?? nullptr, pResult);
      if (err != BiosealError.success.value) {
        calloc.free(pResult);
        throw BiosealException(err);
      }
      return VerificationResult(pResult);
    } finally {
      if (pData != null) {
        calloc.free(pData);
      }
    }
  }

  /// Builds the presentation view, in HTML format.
  ///
  /// param language The expected language.
  /// param userAuthenticated A value indicating whether the user is authenticated.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void buildHtmlView(String? language, bool userAuthenticated) {
    Pointer<Char>? pLanguage = language?.toNativeUtf8().cast<Char>();
    try {
      var err = biosealSDK.id3Bioseal_BuildHtmlView(_pHandle.value, pLanguage ?? nullptr, userAuthenticated);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
    } finally {
      if (pLanguage != null) {
        calloc.free(pLanguage);
      }
    }
  }

  /// Gets the name of the document.
  ///
  /// param language The expected language.
  /// return The name of the document.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getDocumentName(String? language) {
    Pointer<Char>? pLanguage = language?.toNativeUtf8().cast<Char>();
    Pointer<Char> pDocumentName = nullptr;
    Pointer<Int> pDocumentNameSize = calloc.allocate(1);
    pDocumentNameSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetDocumentName(_pHandle.value, pLanguage ?? nullptr, pDocumentName, pDocumentNameSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pDocumentName = calloc.allocate(pDocumentNameSize.value);
        err = biosealSDK.id3Bioseal_GetDocumentName(_pHandle.value, pLanguage ?? nullptr, pDocumentName, pDocumentNameSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vDocumentName = utf8.decode(Uint8List.fromList(pDocumentName.cast<Uint8>().asTypedList(pDocumentNameSize.value)));
      return vDocumentName;
    } finally {
      if (pLanguage != null) {
        calloc.free(pLanguage);
      }
      calloc.free(pDocumentName);
      calloc.free(pDocumentNameSize);
    }
  }

  /// Gets the description of the document.
  ///
  /// param language The expected language.
  /// return The description of the document.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String? getDocumentDescription(String? language) {
    Pointer<Char>? pLanguage = language?.toNativeUtf8().cast<Char>();
    Pointer<Char> pDocumentDescription = nullptr;
    Pointer<Int> pDocumentDescriptionSize = calloc.allocate(1);
    pDocumentDescriptionSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_GetDocumentDescription(_pHandle.value, pLanguage ?? nullptr, pDocumentDescription, pDocumentDescriptionSize);
      if (err == BiosealError.objectDoesNotExist.value) {
        return null;
      }
      if (err == BiosealError.insufficientBuffer.value) {
        pDocumentDescription = calloc.allocate(pDocumentDescriptionSize.value);
        err = biosealSDK.id3Bioseal_GetDocumentDescription(_pHandle.value, pLanguage ?? nullptr, pDocumentDescription, pDocumentDescriptionSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vDocumentDescription = utf8.decode(Uint8List.fromList(pDocumentDescription.cast<Uint8>().asTypedList(pDocumentDescriptionSize.value)));
      return vDocumentDescription;
    } finally {
      if (pLanguage != null) {
        calloc.free(pLanguage);
      }
      calloc.free(pDocumentDescription);
      calloc.free(pDocumentDescriptionSize);
    }
  }

  /// Finds fields by extension type.
  ///
  /// param fieldExtensionType The field extension type.
  /// return The list of fields with the extension.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  FieldList findFieldsByExtension(FieldExtensionType fieldExtensionType) {
    FieldList resultFieldList = FieldList();
    var err = biosealSDK.id3Bioseal_FindFieldsByExtension(_pHandle.value, fieldExtensionType.value, resultFieldList.handle);
    if (err != BiosealError.success.value) {
      resultFieldList.dispose();
      throw BiosealException(err);
    }
    return resultFieldList;
  }

  /// Finds fields by extension name.
  ///
  /// param extensionName A string that identifies the extension name.
  /// return The list of fields with the extension.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  FieldList findFieldsByExtensionName(String? extensionName) {
    Pointer<Char>? pExtensionName = extensionName?.toNativeUtf8().cast<Char>();
    FieldList resultFieldList = FieldList();
    try {
      var err = biosealSDK.id3Bioseal_FindFieldsByExtensionName(_pHandle.value, pExtensionName ?? nullptr, resultFieldList.handle);
      if (err != BiosealError.success.value) {
        resultFieldList.dispose();
        throw BiosealException(err);
      }
      return resultFieldList;
    } finally {
      if (pExtensionName != null) {
        calloc.free(pExtensionName);
      }
    }
  }

  /// Finds the biometric field in payload.
  ///
  /// param biometricDataType The type of biometric data.
  /// param biometricFormat The format of the biometric data.
  /// return The list of fields containing biometric data.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  FieldList findBiometrics(BiometricDataType biometricDataType, String? biometricFormat) {
    Pointer<Char>? pBiometricFormat = biometricFormat?.toNativeUtf8().cast<Char>();
    FieldList resultFieldList = FieldList();
    try {
      var err = biosealSDK.id3Bioseal_FindBiometrics(_pHandle.value, biometricDataType.value, pBiometricFormat ?? nullptr, resultFieldList.handle);
      if (err != BiosealError.success.value) {
        resultFieldList.dispose();
        throw BiosealException(err);
      }
      return resultFieldList;
    } finally {
      if (pBiometricFormat != null) {
        calloc.free(pBiometricFormat);
      }
    }
  }

  /// Builds a representation of the VDS, in JSON format.
  ///
  /// param indentation The indentation of the json string.
  /// return The result.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String buildVdsAsJson(String? indentation) {
    Pointer<Char>? pIndentation = indentation?.toNativeUtf8().cast<Char>();
    Pointer<Char> pResult = nullptr;
    Pointer<Int> pResultSize = calloc.allocate(1);
    pResultSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_BuildVdsAsJson(_pHandle.value, pIndentation ?? nullptr, pResult, pResultSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pResult = calloc.allocate(pResultSize.value);
        err = biosealSDK.id3Bioseal_BuildVdsAsJson(_pHandle.value, pIndentation ?? nullptr, pResult, pResultSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vResult = utf8.decode(Uint8List.fromList(pResult.cast<Uint8>().asTypedList(pResultSize.value)));
      return vResult;
    } finally {
      if (pIndentation != null) {
        calloc.free(pIndentation);
      }
      calloc.free(pResult);
      calloc.free(pResultSize);
    }
  }

  /// Builds a representation of the VDS, in a XML format.
  ///
  /// param language The expected language.
  /// return The result.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String buildVdsAsXml(String? language) {
    Pointer<Char>? pLanguage = language?.toNativeUtf8().cast<Char>();
    Pointer<Char> pResult = nullptr;
    Pointer<Int> pResultSize = calloc.allocate(1);
    pResultSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_BuildVdsAsXml(_pHandle.value, pLanguage ?? nullptr, pResult, pResultSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pResult = calloc.allocate(pResultSize.value);
        err = biosealSDK.id3Bioseal_BuildVdsAsXml(_pHandle.value, pLanguage ?? nullptr, pResult, pResultSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vResult = utf8.decode(Uint8List.fromList(pResult.cast<Uint8>().asTypedList(pResultSize.value)));
      return vResult;
    } finally {
      if (pLanguage != null) {
        calloc.free(pLanguage);
      }
      calloc.free(pResult);
      calloc.free(pResultSize);
    }
  }

  /// Clears the internal download cache.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void clearDownloadCache() {
    var err = biosealSDK.id3Bioseal_ClearDownloadCache(_pHandle.value);
    if (err != BiosealError.success.value) {
      throw BiosealException(err);
    }
  }

  /// Sets the time zone offset in seconds.
  ///
  /// param offsetInSeconds The time zone offset in seconds.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  void setTimeZoneOffset(int offsetInSeconds) {
    var err = biosealSDK.id3Bioseal_SetTimeZoneOffset(_pHandle.value, offsetInSeconds);
    if (err != BiosealError.success.value) {
      throw BiosealException(err);
    }
  }

  /// Computes SHA256.
  ///
  /// param data Input data.
  /// return The result.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  static String computeSha256(Uint8List? data) {
    Pointer<UnsignedChar>? pData;
    if (data != null) {
    	pData = calloc.allocate<UnsignedChar>(data.length);
    	pData.cast<Uint8>().asTypedList(data.length).setAll(0, data);
    }
    Pointer<Char> pResult = nullptr;
    Pointer<Int> pResultSize = calloc.allocate(1);
    pResultSize[0] = -1;
    try {
      var err = biosealSDK.id3Bioseal_ComputeSha256(pData ?? nullptr, data?.length ?? 0, pResult, pResultSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pResult = calloc.allocate(pResultSize.value);
        err = biosealSDK.id3Bioseal_ComputeSha256(pData ?? nullptr, data?.length ?? 0, pResult, pResultSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vResult = utf8.decode(Uint8List.fromList(pResult.cast<Uint8>().asTypedList(pResultSize.value)));
      return vResult;
    } finally {
      if (pData != null) {
        calloc.free(pData);
      }
      calloc.free(pResult);
      calloc.free(pResultSize);
    }
  }

}

