#ifndef CMS_PKI_CIPHER_H_INCLUDED
#define  CMS_PKI_CIPHER_H_INCLUDED

#include <iostream>

#include "pki/icipher.h"
#include "../common/common.h"
#include "../utils/tools.h"
#include "../stdafx.h"

#include "pki.h"
#include "certs.h"
#include "../cms/cert_info.h"
#include "../cms/cert_infos.h"

#include "wrapper/utils/license_mng.h"

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

class Cipher : public ICipher {
public:
	Cipher();
	~Cipher();

	Handle<std::string> getProviderName();

	void setContent(Handle<std::string> value, unsigned long dwSize);

	void encrypt(Handle<std::string> inSource, Handle<std::string> outEnc, EncryptAlg::ENCRYPT_ALG encAlg, DataFormat::DATA_FORMAT format);
	void decrypt(Handle<std::string> inEnc, Handle<std::string> outDec, DataFormat::DATA_FORMAT format);

	void addRecipientsCerts(Handle<ICertificateCollection> certs);
	unsigned long getProvAlgorithm(std::string strPublicKey);
	void setProvAlgorithm(Handle<std::string> strProvType);
	Handle<ICertInfoCollection> getRecipientInfos(Handle<std::string> inEnc, DataFormat::DATA_FORMAT format);

	void setKuPolicy(kuPolicy enmKuPolicy);

	void setPin(std::string pinValue);
	std::string getPin();
	void setStore(Handle<IPkiStore> store);
	Handle<IPkiStore> getStore();

	bool isPinRequired(std::string inEnc, DataFormat::DATA_FORMAT format) ;

	static int
#ifdef _WIN32
		WINAPI
#endif //_WIN32
		WriteFileCallback(
			const void *pvArg,
			unsigned char *pbData,
			unsigned long cbData,
			int fFinal);
	static int
#ifdef _WIN32
		WINAPI
#endif //_WIN32
		EncryptCallback(
			const void *pvArg,
			unsigned char *pbData,
			unsigned long cbData,
			int fFinal);

protected:
	size_t getContentLength();
	std::vector<unsigned char> getContentChunk(size_t offset, size_t length);

	std::string content = "";
	std::string contentFile;
	std::fstream m_contentFileStream;
	std::string m_strOutBuffer;	
	std::vector<PCCERT_CONTEXT> m_pRecipientCert;
	unsigned long m_dwProvAlgorithm;
	FILE * m_pFile = NULL;
	int m_bIsBase64;
	kuPolicy m_enmKuPolicy;
	std::string m_strPin;

	Handle<IPkiStore> m_store;
};

#endif
