#ifndef CMS_PKI_OCSP_H_INCLUDED
#define CMS_PKI_OCSP_H_INCLUDED

#include "pki/iocsp.h"
#include "../common/common.h"
#include "../utils/tools.h"
#include "wrapper/utils/connection_settings.h"
#include "../stdafx.h"
#include "cert.h"
#include "certs.h"

#ifndef TSP_OCSP_CPP_IMPL_IS_DEPRECATED
#include <ocspcli.h>
#else
#include "wrapper/utils/asn1_utils.h"
#endif

class OCSP : public IOCSP
{
public:
    // constructor
    OCSP(Handle<ICertificate> certToCheck, Handle<ConnectionSettings> connSettings);
    OCSP(Handle<std::string> data); // OCSP response import
    ~OCSP();

    Handle<std::string> Export();

    int Verify(Handle<ICertificate> cert = NULL);
    uint32_t VerifyCertificate(Handle<ICertificate> cert);
#ifndef TSP_OCSP_CPP_IMPL_IS_DEPRECATED
    CryptoPro::PKI::OCSP::ResponseStatus RespStatus();
#else
    int RespStatus();
#endif
    Handle<std::string> SignatureAlgorithmOid();
    Handle<ICertificateCollection> Certificates();
    Handle<std::string> ProducedAt();
    unsigned long RespNumber();
    unsigned long RespIndexByCert(Handle<ICertificate> cert, Handle<ICertificate> issuer = NULL);
    Handle<ICertificate> OcspCert(Handle<ICertificateCollection> certToSearch = NULL);
#ifndef TSP_OCSP_CPP_IMPL_IS_DEPRECATED
    CryptoPro::PKI::OCSP::CCertStatus::Type Status(unsigned long respIdx = 0);
#else
    int Status(unsigned long respIdx = 0);
#endif
    Handle<std::string> RevTime(unsigned long respIdx = 0);
#ifndef TSP_OCSP_CPP_IMPL_IS_DEPRECATED
    CryptoPro::ASN1::CrlReason RevReason(unsigned long respIdx = 0);
#else
    int RevReason(unsigned long respIdx = 0);
#endif
    Handle<std::string> ThisUpdate(unsigned long respIdx = 0);
    Handle<std::string> NextUpdate(unsigned long respIdx = 0);

    void setStore(Handle<IPkiStore> store);
    void setSearchCerts(Handle<ICertificateCollection> certsToSearch);

protected:
#ifndef TSP_OCSP_CPP_IMPL_IS_DEPRECATED
    CryptoPro::PKI::OCSP::Client::CResponse ocspResp;
#else
    void decodeBasicSignedResponse(const BYTE *pbEncoded, DWORD cbEncoded);
    int verifyRespSign(Handle<ICertificate> cert = NULL);
    HCERTSTORE CollectionToHstore(Handle<ICertificateCollection> certCollection);
    Handle<ICertificate> findOcspCert(Handle<ICertificateCollection> certsToSearch = NULL);
    Handle<ICertificate> findOcspCertInStore(HCERTSTORE hStore);

    DWORD m_respStatus;
    Handle<std::string> m_signAlgOid;
    Handle<ICertificate> m_respSigningCert;

    POCSP_RESPONSE_INFO m_pResponse;
    POCSP_BASIC_SIGNED_RESPONSE_INFO m_pBasicSignedResponse;
    POCSP_BASIC_RESPONSE_INFO m_pBasicResponse;

    AsnUtils m_AsnUtils;
#endif // TSP_OCSP_CPP_IMPL_IS_DEPRECATED
    Handle<IPkiStore> m_store;
    Handle<ICertificateCollection> m_certsToSearch;
};

#endif //! CMS_PKI_OCSP_H_INCLUDED
