#ifndef CMS_PKI_TSP_H_INCLUDED
#define CMS_PKI_TSP_H_INCLUDED

#include "pki/itsp.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 <tspcli.h>
#else
#include "wrapper/utils/asn1_utils.h"
#endif

class TSP;

class TSPRequest : ITSPRequest {
public:
    TSPRequest(const std::string& hashAlgOid);
    TSPRequest(const std::string& hashAlgOid, const std::string& dataFileName); // TSP response import
    ~TSPRequest();

    friend TSP;

    void AddData(Handle<std::string> data);
    void AddData(std::string& data);
    bool GetCertReq();
    void SetCertReq(bool certReq);
    bool GetNonce();
    void SetNonce(bool useNonce);
    std::string GetPolicyId();
    void SetPolicyId(std::string policyId);
    std::string GetHashAlgOid();
    void SetHashAlgOid(std::string hashAlgOid);
    Handle<std::string> GetDataHash();
    void SetDataHash(Handle<std::string> dataHash);

protected:
#ifndef TSP_OCSP_CPP_IMPL_IS_DEPRECATED
    CryptoPro::PKI::TSP::Client::CRequest tspReq;
#endif
};

class TSP : public ITSP {
public:
    TSP(Handle<TSPRequest> request, Handle<ConnectionSettings> connSettings);
    TSP(Handle<std::string> data); // TSP response import
    ~TSP();

    Handle<std::string> Export();
    Handle<ICertificateCollection> Certificates();
    Handle<ICertificate> TSACertificate();

    int Verify();
    int VerifyCertificate(Handle<ICertificate> cert);
    unsigned int FailInfo();
    unsigned int Status();
    std::wstring StatusString();
    std::string DataHashAlgOID();
    Handle<std::string> DataHash();
    std::string PolicyID();
    Handle<std::string> SerialNumber();
    std::string Time();
    long Accuracy();
    bool Ordering();
    bool HasNonce();
    std::wstring TsaName();
    Handle<std::string> TsaNameBlob();

    void setStore(Handle<IPkiStore> store);

protected:
#ifndef TSP_OCSP_CPP_IMPL_IS_DEPRECATED
    CryptoPro::PKI::TSP::Client::CStamp tspResp;
#else
    PCRYPT_TIMESTAMP_RESPONSE m_pTimestampResp;
    PCRYPT_TIMESTAMP_INFO m_pInfo;
    Handle<std::string> m_stampSignatureData;

    AsnUtils m_AsnUtils;
#endif

    Handle<IPkiStore> m_store;
};

#endif //!CMS_PKI_TSP_H_INCLUDED
