#ifndef CMS_PKI_CERTREG_H_INCLUDED
#define  CMS_PKI_CERTREG_H_INCLUDED

#include "pki/icert_request.h"
#include "../common/common.h"

#include "pki.h"
#include "exts.h"
#include "../utils/tools.h"
#include "wrapper/utils/license_mng.h"
#include "wrapper/utils/smartbuffer.h"
#include "cert.h"

#ifndef DLV_AND_JWT_NO_LICENSE
extern License_Mng* m_objLicense;
#endif // !DLV_AND_JWT_NO_LICENSE

class CertificationRequest : public ICertificationRequest
{
public:
	CertificationRequest();
	~CertificationRequest();

	void write(Handle < std::string > out, DataFormat::DATA_FORMAT format);
	void generateRequest();
	Handle<ICertificate> toCertificate(time_t notBefore, time_t notAfter, std::string serial);

	void setSubject(Handle<std::string> x509Name);
	void setVersion(long version);
	void setExtensions(Handle<IExtensionCollection> exts);
	void setPubKeyAlgorithm(Handle<std::string> algorithm);
	void setExportableFlag(bool flag);
	void setNewKeysetFlag(bool flag);
	void setContainerName(Handle<std::string> containerName);
	void setSerialNumber(Handle<std::string> serial);
	void setKeyUsagePeriodFromContainer(bool value);
	void setKeyPassword(Handle<std::string> passwd);

	CERT_NAME_BLOB getSubjectBlob();
	Handle<std::string> getSubject();
	unsigned long getVersion();
	Handle<IExtensionCollection> getExtensions();
	PCERT_EXTENSIONS getExtensionsPcert();
	Handle<std::string> getPubKeyAlgorithm();
	bool getExportableFlag();
	bool getNewKeysetFlag();
	Handle<std::string> getContainerName();
	unsigned long getProvType();
	Handle<std::string> getSerialNumber();
	bool getKeyUsagePeriodFromContainer();
	Handle<std::string> getKeyPassword();

	void setProvider(Handle<IProvider> provider);

	std::string getProviderName();

private:
	void EncodeString(std::string stringToEncode, PCRYPT_DER_BLOB resultBlob);
	void EncodeTimeForPrivKeyUsagePeriod(FILETIME& timeToEncrypt, PCRYPT_DER_BLOB resultBlob);
	void EncodeSequence(PCRYPT_SEQUENCE_OF_ANY seqToEncode, PCRYPT_DER_BLOB resultBlob);

	PCERT_EXTENSION addExtention();

	BOOL m_isExportable = FALSE;
	BOOL m_isNewKeyset = TRUE;
	BOOL m_bKeyUsagePeriodFromContainer = TRUE;

	CSmartBuffer<BYTE> m_smartBufferByteCertNameInfo;
	CSmartBuffer<CERT_NAME_INFO> m_smartBufferCertNameInfo;
	PCERT_NAME_INFO m_pCertNameInfo;
	//PCERT_RDN m_rgNameAttrArray;

	DWORD m_dwVersion = CERT_V3;
	DWORD m_dwProvType;

	CSmartBuffer<BYTE> m_smartBufferByteSignedEncodedCertReq;
	CSmartBuffer<CRYPT_DATA_BLOB> m_smartBufferSignedEncodedCertReq;
	PCRYPT_DATA_BLOB m_pSignedEncodedCertReq;
	CSmartBuffer<BYTE> m_smartBufferByteCertExtensions;
	CSmartBuffer<CERT_EXTENSION> m_smartBufferCertExtension;
	CSmartBuffer<CERT_EXTENSIONS> m_smartBufferCertExtensions;
	PCERT_EXTENSIONS m_pCertExtensions;
	ExtensionCollection m_exts;

	std::string m_strPubKeyAlg;
	std::string m_strContainerName;
	std::string m_strSerialNumber;

	// Key generated for certificate
	HCRYPTKEY m_hKey;
	// Provider for certificate's key
	HCRYPTPROV  m_hKeyProv;
};

#endif
