//--------------------------------------------------------------------------------------------------
// Copyright (c) id3 Technologies
// All Rights Reserved.
//--------------------------------------------------------------------------------------------------
#pragma once
#include <id3BiosealCppWrapper/id3BiosealException.hpp>
#include <id3BiosealCppWrapper/id3BiosealDateTime.hpp>
#include <id3BiosealCppWrapper/id3BiosealField.hpp>
#include <id3BiosealCppWrapper/id3BiosealManifest.hpp>
#include <id3BiosealCppWrapper/id3BiosealStringArray.hpp>
#include <id3BiosealCppWrapper/id3BiosealCertificateInformation.hpp>
#include <id3BiosealCppWrapper/id3BiosealBiometricVerificationRules.hpp>
#include <id3BiosealCppWrapper/id3BiosealLog.hpp>
#include <id3BiosealCppWrapper/id3BiosealUserAuthentication.hpp>
#include <id3BiosealCppWrapper/id3BiosealFieldList.hpp>
#include <id3Bioseal/id3Bioseal.h>
#include "vector"

namespace id3BiosealCppWrapper
{

/**
 * Represents a BioSeal code.
 */
class Bioseal
{
private:
    ID3_BIOSEAL handle_{};

public:
    Bioseal() {
        check_error(id3Bioseal_Initialize(&handle_));
    }

    virtual ~Bioseal() {
        if (handle_) {
            id3Bioseal_Dispose(&handle_);
        }
    }


    Bioseal(Bioseal &&src) noexcept: handle_(src.handle_) {
        src.handle_ = nullptr;
    }

    ID3_BIOSEAL getHandle() const { return handle_; }
    operator ID3_BIOSEAL () const { return handle_; }

    // public getters and setters
    /**
    * Gets the the BioSeal format without prefix information.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The BioSeal format without prefix information.
    */
    id3BiosealFormat getFormat() {
        id3BiosealFormat format;
        check_error(id3Bioseal_GetFormat(handle_, &format));
        return format;
    }

    /**
    * Gets the the BioSeal format with prefix information.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The BioSeal format with prefix information.
    */
    id3BiosealFormat getExtendedFormat() {
        id3BiosealFormat extended_format;
        check_error(id3Bioseal_GetExtendedFormat(handle_, &extended_format));
        return extended_format;
    }

    /**
    * Gets the the document issuing date.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The document issuing date.
    */
    DateTime getDocumentIssuingDate() {
        DateTime document_issuing_date;
        check_error(id3Bioseal_GetDocumentIssuingDate(handle_, document_issuing_date));
        return document_issuing_date;
    }

    /**
    * Gets the the BioSeal signature date.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The BioSeal signature date.
    */
    DateTime getSignatureDate() {
        DateTime signature_date;
        check_error(id3Bioseal_GetSignatureDate(handle_, signature_date));
        return signature_date;
    }

    /**
    * Gets the the document type identification code. For AFNOR XP Z42-101 only.
    * @param documentType [out] The document type identification code. For AFNOR XP Z42-101 only.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The document type identification code. For AFNOR XP Z42-101 only.
    */
    void getDocumentType(std::string & documentType) {
        int documentTypeSize = -1;
        auto err = id3Bioseal_GetDocumentType(handle_, documentType.data(), &documentTypeSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            documentType.resize(documentTypeSize);
            err = id3Bioseal_GetDocumentType(handle_, documentType.data(), &documentTypeSize);
            if (err == 0) { documentType.resize(documentTypeSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the document type identification code. For AFNOR XP Z42-101 only.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The document type identification code. For AFNOR XP Z42-101 only.
    */
    std::string getDocumentType() {
        std::string document_type;
        getDocumentType(document_type);
        return document_type;
    }

    /**
    * Gets the the identification code of the scope on which the document type is defined. For AFNOR XP Z42-101 only.
    * @param documentScope [out] The identification code of the scope on which the document type is defined. For AFNOR XP Z42-101 only.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The identification code of the scope on which the document type is defined. For AFNOR XP Z42-101 only.
    */
    void getDocumentScope(std::string & documentScope) {
        int documentScopeSize = -1;
        auto err = id3Bioseal_GetDocumentScope(handle_, documentScope.data(), &documentScopeSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            documentScope.resize(documentScopeSize);
            err = id3Bioseal_GetDocumentScope(handle_, documentScope.data(), &documentScopeSize);
            if (err == 0) { documentScope.resize(documentScopeSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the identification code of the scope on which the document type is defined. For AFNOR XP Z42-101 only.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The identification code of the scope on which the document type is defined. For AFNOR XP Z42-101 only.
    */
    std::string getDocumentScope() {
        std::string document_scope;
        getDocumentScope(document_scope);
        return document_scope;
    }

    /**
    * Gets the the identifier of the country issuing the document. For AFNOR XP Z42-101 only.
    * @param documentIssuingCountry [out] The identifier of the country issuing the document. For AFNOR XP Z42-101 only.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The identifier of the country issuing the document. For AFNOR XP Z42-101 only.
    */
    void getDocumentIssuingCountry(std::string & documentIssuingCountry) {
        int documentIssuingCountrySize = -1;
        auto err = id3Bioseal_GetDocumentIssuingCountry(handle_, documentIssuingCountry.data(), &documentIssuingCountrySize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            documentIssuingCountry.resize(documentIssuingCountrySize);
            err = id3Bioseal_GetDocumentIssuingCountry(handle_, documentIssuingCountry.data(), &documentIssuingCountrySize);
            if (err == 0) { documentIssuingCountry.resize(documentIssuingCountrySize); }
        }
        check_error(err);
    }

    /**
    * Gets the the identifier of the country issuing the document. For AFNOR XP Z42-101 only.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The identifier of the country issuing the document. For AFNOR XP Z42-101 only.
    */
    std::string getDocumentIssuingCountry() {
        std::string document_issuing_country;
        getDocumentIssuingCountry(document_issuing_country);
        return document_issuing_country;
    }

    /**
    * Gets the the manifest ID in ISO 22385 format.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The manifest ID in ISO 22385 format.
    */
    int getManifestId() {
        int manifest_id;
        check_error(id3Bioseal_GetManifestId(handle_, &manifest_id));
        return manifest_id;
    }

    /**
    * Gets the the payload containing the data specific to the BioSeal.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The payload containing the data specific to the BioSeal.
    */
    Field getPayload() {
        Field payload;
        check_error(id3Bioseal_GetPayload(handle_, payload));
        return payload;
    }

    /**
    * Gets the the manifest information.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The manifest information.
    */
    Manifest getManifest() {
        Manifest manifest;
        check_error(id3Bioseal_GetManifest(handle_, manifest));
        return manifest;
    }

    /**
    * Gets the indicates whether the BioSeal contains images.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the BioSeal contains images.
    */
    bool getContainsImages() {
        bool contains_images;
        check_error(id3Bioseal_GetContainsImages(handle_, &contains_images));
        return contains_images;
    }

    /**
    * Gets the indicates whether the BioSeal contains portraits.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the BioSeal contains portraits.
    */
    bool getContainsPortraits() {
        bool contains_portraits;
        check_error(id3Bioseal_GetContainsPortraits(handle_, &contains_portraits));
        return contains_portraits;
    }

    /**
    * Gets the indicates whether the BioSeal contains biometric data.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the BioSeal contains biometric data.
    */
    bool getContainsBiometrics() {
        bool contains_biometrics;
        check_error(id3Bioseal_GetContainsBiometrics(handle_, &contains_biometrics));
        return contains_biometrics;
    }

    /**
    * Gets the indicates whether the BioSeal contains face templates.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the BioSeal contains face templates.
    */
    bool getContainsFaceTemplates() {
        bool contains_face_templates;
        check_error(id3Bioseal_GetContainsFaceTemplates(handle_, &contains_face_templates));
        return contains_face_templates;
    }

    /**
    * Gets the indicates whether the BioSeal contains finger templates.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the BioSeal contains finger templates.
    */
    bool getContainsFingerTemplates() {
        bool contains_finger_templates;
        check_error(id3Bioseal_GetContainsFingerTemplates(handle_, &contains_finger_templates));
        return contains_finger_templates;
    }

    /**
    * Gets the indicates whether the BioSeal contains extensions.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the BioSeal contains extensions.
    */
    bool getContainsExtensions() {
        bool contains_extensions;
        check_error(id3Bioseal_GetContainsExtensions(handle_, &contains_extensions));
        return contains_extensions;
    }

    /**
    * Gets the the list of supported languages declared in the manifest.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The list of supported languages declared in the manifest.
    */
    StringArray getSupportedLanguages() {
        StringArray supported_languages;
        check_error(id3Bioseal_GetSupportedLanguages(handle_, supported_languages));
        return supported_languages;
    }

    /**
    * Gets the the presentation view, in HTML format, created from the manifest and the data contained in the BioSeal.
    * @param htmlView [out] The presentation view, in HTML format, created from the manifest and the data contained in the BioSeal.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The presentation view, in HTML format, created from the manifest and the data contained in the BioSeal.
    */
    void getHtmlView(std::string & htmlView) {
        int htmlViewSize = -1;
        auto err = id3Bioseal_GetHtmlView(handle_, htmlView.data(), &htmlViewSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            htmlView.resize(htmlViewSize);
            err = id3Bioseal_GetHtmlView(handle_, htmlView.data(), &htmlViewSize);
            if (err == 0) { htmlView.resize(htmlViewSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the presentation view, in HTML format, created from the manifest and the data contained in the BioSeal.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The presentation view, in HTML format, created from the manifest and the data contained in the BioSeal.
    */
    std::string getHtmlView() {
        std::string html_view;
        getHtmlView(html_view);
        return html_view;
    }

    /**
    * Sets the the callback used to retrieve an external resource (LoTL, TSL, certificate, manifest, CRL) with specified URI.
    * @param externalResourceCallback [in] The callback used to retrieve an external resource (LoTL, TSL, certificate, manifest, CRL) with specified URI.
    * @param context [in] The callback context.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void setExternalResourceCallback(id3BiosealResourceCallbackHandler externalResourceCallback, void *context) {
        check_error(id3Bioseal_SetExternalResourceCallback(handle_, externalResourceCallback, context));
    }

    /**
    * Gets the the issuing reference of the certificate authority.
    * @param certificateAuthorityReference [out] The issuing reference of the certificate authority.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The issuing reference of the certificate authority.
    */
    void getCertificateAuthorityReference(std::string & certificateAuthorityReference) {
        int certificateAuthorityReferenceSize = -1;
        auto err = id3Bioseal_GetCertificateAuthorityReference(handle_, certificateAuthorityReference.data(), &certificateAuthorityReferenceSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            certificateAuthorityReference.resize(certificateAuthorityReferenceSize);
            err = id3Bioseal_GetCertificateAuthorityReference(handle_, certificateAuthorityReference.data(), &certificateAuthorityReferenceSize);
            if (err == 0) { certificateAuthorityReference.resize(certificateAuthorityReferenceSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the issuing reference of the certificate authority.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The issuing reference of the certificate authority.
    */
    std::string getCertificateAuthorityReference() {
        std::string certificate_authority_reference;
        getCertificateAuthorityReference(certificate_authority_reference);
        return certificate_authority_reference;
    }

    /**
    * Gets the the identifier of the certificate.
    * @param certificateIdentifier [out] The identifier of the certificate.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The identifier of the certificate.
    */
    void getCertificateIdentifier(std::string & certificateIdentifier) {
        int certificateIdentifierSize = -1;
        auto err = id3Bioseal_GetCertificateIdentifier(handle_, certificateIdentifier.data(), &certificateIdentifierSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            certificateIdentifier.resize(certificateIdentifierSize);
            err = id3Bioseal_GetCertificateIdentifier(handle_, certificateIdentifier.data(), &certificateIdentifierSize);
            if (err == 0) { certificateIdentifier.resize(certificateIdentifierSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the identifier of the certificate.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The identifier of the certificate.
    */
    std::string getCertificateIdentifier() {
        std::string certificate_identifier;
        getCertificateIdentifier(certificate_identifier);
        return certificate_identifier;
    }

    /**
    * Gets the the detailed certificate information.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The detailed certificate information.
    */
    CertificateInformation getCertificateInformation() {
        CertificateInformation certificate_information;
        check_error(id3Bioseal_GetCertificateInformation(handle_, certificate_information));
        return certificate_information;
    }

    /**
    * Gets the the BioSeal expiration date.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The BioSeal expiration date.
    */
    DateTime getExpirationDate() {
        DateTime expiration_date;
        check_error(id3Bioseal_GetExpirationDate(handle_, expiration_date));
        return expiration_date;
    }

    /**
    * Gets the indicates whether the BioSeal contains auxiliary data.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the BioSeal contains auxiliary data.
    */
    bool getContainsAuxData() {
        bool contains_aux_data;
        check_error(id3Bioseal_GetContainsAuxData(handle_, &contains_aux_data));
        return contains_aux_data;
    }

    /**
    * Gets the the auxiliary data containing additional information specific to the BioSeal.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The auxiliary data containing additional information specific to the BioSeal.
    */
    Field getAuxData() {
        Field aux_data;
        check_error(id3Bioseal_GetAuxData(handle_, aux_data));
        return aux_data;
    }

    /**
    * Gets the the list of biometric verification rules.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The list of biometric verification rules.
    */
    BiometricVerificationRules getBiometricVerificationRules() {
        BiometricVerificationRules biometric_verification_rules;
        check_error(id3Bioseal_GetBiometricVerificationRules(handle_, biometric_verification_rules));
        return biometric_verification_rules;
    }

    /**
    * Gets the the log.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The log.
    */
    Log getLog() {
        Log log;
        check_error(id3Bioseal_GetLog(handle_, log));
        return log;
    }

    /**
    * Gets the the user authentication parameters.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The user authentication parameters.
    */
    UserAuthentication getUserAuthentication() {
        UserAuthentication user_authentication;
        check_error(id3Bioseal_GetUserAuthentication(handle_, user_authentication));
        return user_authentication;
    }

    /**
    * Gets the the header version.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The header version.
    */
    int getHeaderVersion() {
        int header_version;
        check_error(id3Bioseal_GetHeaderVersion(handle_, &header_version));
        return header_version;
    }

    /**
    * Sets the the callback used to decrypt a field.
    * @param decryptionCallback [in] The callback used to decrypt a field.
    * @param context [in] The callback context.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void setDecryptionCallback(id3BiosealDecryptionCallbackHandler decryptionCallback, void *context) {
        check_error(id3Bioseal_SetDecryptionCallback(handle_, decryptionCallback, context));
    }

    /**
    * Gets the indicates whether the governance certification chain is verified.
    * Hint: Default value is true.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the governance certification chain is verified.
    */
    bool getVerifiesGovernance() {
        bool verifies_governance;
        check_error(id3Bioseal_GetVerifiesGovernance(handle_, &verifies_governance));
        return verifies_governance;
    }

    /**
    * Sets the indicates whether the governance certification chain is verified.
    * Hint: Default value is true.
    * @param verifiesGovernance [in] Indicates whether the governance certification chain is verified.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void setVerifiesGovernance(bool verifiesGovernance) {
        check_error(id3Bioseal_SetVerifiesGovernance(handle_, verifiesGovernance));
    }

    /**
    * Gets the indicates whether the VDS signature is verified.
    * Hint: Default value is true.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the VDS signature is verified.
    */
    bool getVerifiesSignature() {
        bool verifies_signature;
        check_error(id3Bioseal_GetVerifiesSignature(handle_, &verifies_signature));
        return verifies_signature;
    }

    /**
    * Sets the indicates whether the VDS signature is verified.
    * Hint: Default value is true.
    * @param verifiesSignature [in] Indicates whether the VDS signature is verified.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void setVerifiesSignature(bool verifiesSignature) {
        check_error(id3Bioseal_SetVerifiesSignature(handle_, verifiesSignature));
    }

    /**
    * Gets the indicates whether the verification process should verify the next CRL update.
    * Hint: Default value is true.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Indicates whether the verification process should verify the next CRL update.
    */
    bool getVerifiesCrlUpdates() {
        bool verifies_crl_updates;
        check_error(id3Bioseal_GetVerifiesCrlUpdates(handle_, &verifies_crl_updates));
        return verifies_crl_updates;
    }

    /**
    * Sets the indicates whether the verification process should verify the next CRL update.
    * Hint: Default value is true.
    * @param verifiesCrlUpdates [in] Indicates whether the verification process should verify the next CRL update.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void setVerifiesCrlUpdates(bool verifiesCrlUpdates) {
        check_error(id3Bioseal_SetVerifiesCrlUpdates(handle_, verifiesCrlUpdates));
    }

    /**
    * Gets the the last verification result.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The last verification result.
    */
    id3BiosealVerificationResult getVerificationResult() {
        id3BiosealVerificationResult verification_result;
        check_error(id3Bioseal_GetVerificationResult(handle_, &verification_result));
        return verification_result;
    }

    /**
    * Gets the the URL to the LoTL (List of Trust List).
    * @param lotlUrl [out] The URL to the LoTL (List of Trust List).
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The URL to the LoTL (List of Trust List).
    */
    void getLotlUrl(std::string & lotlUrl) {
        int lotlUrlSize = -1;
        auto err = id3Bioseal_GetLotlUrl(handle_, lotlUrl.data(), &lotlUrlSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            lotlUrl.resize(lotlUrlSize);
            err = id3Bioseal_GetLotlUrl(handle_, lotlUrl.data(), &lotlUrlSize);
            if (err == 0) { lotlUrl.resize(lotlUrlSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the URL to the LoTL (List of Trust List).
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The URL to the LoTL (List of Trust List).
    */
    std::string getLotlUrl() {
        std::string lotl_url;
        getLotlUrl(lotl_url);
        return lotl_url;
    }

    /**
    * Sets the the URL to the LoTL (List of Trust List).
    * @param lotlUrl [in] The URL to the LoTL (List of Trust List).
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void setLotlUrl(const char *lotlUrl) {
        check_error(id3Bioseal_SetLotlUrl(handle_, lotlUrl));
    }

    /**
    * Gets the the URL to the TSL (Trust Service List).
    * @param tslUrl [out] The URL to the TSL (Trust Service List).
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The URL to the TSL (Trust Service List).
    */
    void getTslUrl(std::string & tslUrl) {
        int tslUrlSize = -1;
        auto err = id3Bioseal_GetTslUrl(handle_, tslUrl.data(), &tslUrlSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            tslUrl.resize(tslUrlSize);
            err = id3Bioseal_GetTslUrl(handle_, tslUrl.data(), &tslUrlSize);
            if (err == 0) { tslUrl.resize(tslUrlSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the URL to the TSL (Trust Service List).
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The URL to the TSL (Trust Service List).
    */
    std::string getTslUrl() {
        std::string tsl_url;
        getTslUrl(tsl_url);
        return tsl_url;
    }

    /**
    * Sets the the URL to the TSL (Trust Service List).
    * @param tslUrl [in] The URL to the TSL (Trust Service List).
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void setTslUrl(const char *tslUrl) {
        check_error(id3Bioseal_SetTslUrl(handle_, tslUrl));
    }

    /**
    * Gets the the URL to the manifest.
    * @param manifestUrl [out] The URL to the manifest.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The URL to the manifest.
    */
    void getManifestUrl(std::string & manifestUrl) {
        int manifestUrlSize = -1;
        auto err = id3Bioseal_GetManifestUrl(handle_, manifestUrl.data(), &manifestUrlSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            manifestUrl.resize(manifestUrlSize);
            err = id3Bioseal_GetManifestUrl(handle_, manifestUrl.data(), &manifestUrlSize);
            if (err == 0) { manifestUrl.resize(manifestUrlSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the URL to the manifest.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The URL to the manifest.
    */
    std::string getManifestUrl() {
        std::string manifest_url;
        getManifestUrl(manifest_url);
        return manifest_url;
    }

    /**
    * Sets the the URL to the manifest.
    * @param manifestUrl [in] The URL to the manifest.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void setManifestUrl(const char *manifestUrl) {
        check_error(id3Bioseal_SetManifestUrl(handle_, manifestUrl));
    }

    /**
    * Gets the the Issuing Agency Code (IAC). For ISO 22376:2023 format only.
    * @param issuingAgencyCode [out] The Issuing Agency Code (IAC). For ISO 22376:2023 format only.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The Issuing Agency Code (IAC). For ISO 22376:2023 format only.
    */
    void getIssuingAgencyCode(std::string & issuingAgencyCode) {
        int issuingAgencyCodeSize = -1;
        auto err = id3Bioseal_GetIssuingAgencyCode(handle_, issuingAgencyCode.data(), &issuingAgencyCodeSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            issuingAgencyCode.resize(issuingAgencyCodeSize);
            err = id3Bioseal_GetIssuingAgencyCode(handle_, issuingAgencyCode.data(), &issuingAgencyCodeSize);
            if (err == 0) { issuingAgencyCode.resize(issuingAgencyCodeSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the Issuing Agency Code (IAC). For ISO 22376:2023 format only.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The Issuing Agency Code (IAC). For ISO 22376:2023 format only.
    */
    std::string getIssuingAgencyCode() {
        std::string issuing_agency_code;
        getIssuingAgencyCode(issuing_agency_code);
        return issuing_agency_code;
    }

    /**
    * Gets the prefix is present.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Prefix is present.
    */
    bool getHasPrefix() {
        bool has_prefix;
        check_error(id3Bioseal_GetHasPrefix(handle_, &has_prefix));
        return has_prefix;
    }

    /**
    * Gets the the prefix.
    * @param prefix [out] The prefix.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The prefix.
    */
    void getPrefix(std::string & prefix) {
        int prefixSize = -1;
        auto err = id3Bioseal_GetPrefix(handle_, prefix.data(), &prefixSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            prefix.resize(prefixSize);
            err = id3Bioseal_GetPrefix(handle_, prefix.data(), &prefixSize);
            if (err == 0) { prefix.resize(prefixSize); }
        }
        check_error(err);
    }

    /**
    * Gets the the prefix.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The prefix.
    */
    std::string getPrefix() {
        std::string prefix;
        getPrefix(prefix);
        return prefix;
    }

    /**
    * Gets the the data of the VDS as a binary array.
    * @param data [out] The data of the VDS as a binary array.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The data of the VDS as a binary array.
    */
    void getData(std::vector<unsigned char> & data) {
        int dataSize = -1;
        auto err = id3Bioseal_GetData(handle_, data.data(), &dataSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            data.resize(dataSize);
            err = id3Bioseal_GetData(handle_, data.data(), &dataSize);
        }
        check_error(err);
    }

    /**
    * Gets the the data of the VDS as a binary array.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The data of the VDS as a binary array.
    */
    std::vector<unsigned char> getData() {
        std::vector<unsigned char> data;
        getData(data);
        return data;
    }

    // public methods
    /**
    * Clears all internal data.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void clear() {
        check_error(id3Bioseal_Clear(handle_));
    }

    /**
    * Decodes and verifies the specified data buffer.
    * @param data [in] The data buffer containing the BioSeal code.
    * @param dataSize [in] Size of the 'data' buffer.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Receives the verification results.
    */
    id3BiosealVerificationResult verifyFromBuffer(unsigned char *data, int dataSize) {
        id3BiosealVerificationResult result;
        check_error(id3Bioseal_VerifyFromBuffer(handle_, data, dataSize, &result));
        return result;
    }

    /**
    * Decodes and verifies the specified string buffer.
    * @param data [in] The string buffer containing the BioSeal code.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Receives the verification results.
    */
    id3BiosealVerificationResult verifyFromString(const char *data) {
        id3BiosealVerificationResult result;
        check_error(id3Bioseal_VerifyFromString(handle_, data, &result));
        return result;
    }

    /**
    * Builds the presentation view, in HTML format.
    * @param language [in] The expected language.
    * @param userAuthenticated [in] A value indicating whether the user is authenticated.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void buildHtmlView(const char *language, bool userAuthenticated) {
        check_error(id3Bioseal_BuildHtmlView(handle_, language, userAuthenticated));
    }

    /**
    * Gets the name of the document.
    * @param language [in] The expected language.
    * @param documentName [out] The name of the document.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The name of the document.
    */
    void getDocumentName(const char *language, std::string & documentName) {
        int documentNameSize = -1;
        auto err = id3Bioseal_GetDocumentName(handle_, language, documentName.data(), &documentNameSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            documentName.resize(documentNameSize);
            err = id3Bioseal_GetDocumentName(handle_, language, documentName.data(), &documentNameSize);
            if (err == 0) { documentName.resize(documentNameSize); }
        }
        check_error(err);
    }

    /**
    * Gets the name of the document.
    * @param language [in] The expected language.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The name of the document.
    */
    std::string getDocumentName(const char *language) {
        std::string document_name;
        getDocumentName(language, document_name);
        return document_name;
    }

    /**
    * Gets the description of the document.
    * @param language [in] The expected language.
    * @param documentDescription [out] The description of the document.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The description of the document.
    */
    void getDocumentDescription(const char *language, std::string & documentDescription) {
        int documentDescriptionSize = -1;
        auto err = id3Bioseal_GetDocumentDescription(handle_, language, documentDescription.data(), &documentDescriptionSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            documentDescription.resize(documentDescriptionSize);
            err = id3Bioseal_GetDocumentDescription(handle_, language, documentDescription.data(), &documentDescriptionSize);
            if (err == 0) { documentDescription.resize(documentDescriptionSize); }
        }
        check_error(err);
    }

    /**
    * Gets the description of the document.
    * @param language [in] The expected language.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The description of the document.
    */
    std::string getDocumentDescription(const char *language) {
        std::string document_description;
        getDocumentDescription(language, document_description);
        return document_description;
    }

    /**
    * Finds fields by extension type.
    * @param fieldExtensionType [in] The field extension type.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The list of fields with the extension.
    */
    FieldList findFieldsByExtension(id3BiosealFieldExtensionType fieldExtensionType) {
        FieldList result_field_list;
        check_error(id3Bioseal_FindFieldsByExtension(handle_, fieldExtensionType, result_field_list));
        return result_field_list;
    }

    /**
    * Finds fields by extension name.
    * @param extensionName [in] A string that identifies the extension name.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The list of fields with the extension.
    */
    FieldList findFieldsByExtensionName(const char *extensionName) {
        FieldList result_field_list;
        check_error(id3Bioseal_FindFieldsByExtensionName(handle_, extensionName, result_field_list));
        return result_field_list;
    }

    /**
    * Finds the biometric field in payload.
    * @param biometricDataType [in] The type of biometric data.
    * @param biometricFormat [in] The format of the biometric data.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The list of fields containing biometric data.
    */
    FieldList findBiometrics(id3BiosealBiometricDataType biometricDataType, const char *biometricFormat) {
        FieldList result_field_list;
        check_error(id3Bioseal_FindBiometrics(handle_, biometricDataType, biometricFormat, result_field_list));
        return result_field_list;
    }

    /**
    * Builds a representation of the VDS, in JSON format.
    * @param indentation [in] The indentation of the json string.
    * @param result [out] The result.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    void buildVdsAsJson(const char *indentation, std::string & result) {
        int resultSize = -1;
        auto err = id3Bioseal_BuildVdsAsJson(handle_, indentation, result.data(), &resultSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            result.resize(resultSize);
            err = id3Bioseal_BuildVdsAsJson(handle_, indentation, result.data(), &resultSize);
            if (err == 0) { result.resize(resultSize); }
        }
        check_error(err);
    }

    /**
    * Builds a representation of the VDS, in JSON format.
    * @param indentation [in] The indentation of the json string.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    std::string buildVdsAsJson(const char *indentation) {
        std::string result;
        buildVdsAsJson(indentation, result);
        return result;
    }

    /**
    * Builds a representation of the VDS, in a XML format.
    * @param language [in] The expected language.
    * @param result [out] The result.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    void buildVdsAsXml(const char *language, std::string & result) {
        int resultSize = -1;
        auto err = id3Bioseal_BuildVdsAsXml(handle_, language, result.data(), &resultSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            result.resize(resultSize);
            err = id3Bioseal_BuildVdsAsXml(handle_, language, result.data(), &resultSize);
            if (err == 0) { result.resize(resultSize); }
        }
        check_error(err);
    }

    /**
    * Builds a representation of the VDS, in a XML format.
    * @param language [in] The expected language.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    std::string buildVdsAsXml(const char *language) {
        std::string result;
        buildVdsAsXml(language, result);
        return result;
    }

    /**
    * Clears the internal download cache.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void clearDownloadCache() {
        check_error(id3Bioseal_ClearDownloadCache(handle_));
    }

    /**
    * Sets the time zone offset in seconds.
    * @param offsetInSeconds [in] The time zone offset in seconds.
    * @exception BiosealException An error has occured during Bioseal library execution.
    */
    void setTimeZoneOffset(int offsetInSeconds) {
        check_error(id3Bioseal_SetTimeZoneOffset(handle_, offsetInSeconds));
    }

    /**
    * Computes SHA256.
    * @param data [in] Input data.
    * @param dataSize [in] Size of the 'data' buffer.
    * @param result [out] The result.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    static void computeSha256(unsigned char *data, int dataSize, std::string & result) {
        int resultSize = -1;
        auto err = id3Bioseal_ComputeSha256(data, dataSize, result.data(), &resultSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            result.resize(resultSize);
            err = id3Bioseal_ComputeSha256(data, dataSize, result.data(), &resultSize);
            if (err == 0) { result.resize(resultSize); }
        }
        check_error(err);
    }

    /**
    * Computes SHA256.
    * @param data [in] Input data.
    * @param dataSize [in] Size of the 'data' buffer.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval The result.
    */
    static std::string computeSha256(unsigned char *data, int dataSize) {
        std::string result;
        computeSha256(data, dataSize, result);
        return result;
    }

};
};