#ifndef UTILS_TOOLS_H_INCLUDED
#define  UTILS_TOOLS_H_INCLUDED
#include "../common/common.h"

#include "utils/itools.h"
#include "wrapper/utils/smartbuffer.h"
#include "../pki/pki.h"

class Tools : public ITools {
public:
	Tools() {};
	~Tools() {};

	Handle<std::string> stringFromBase64(std::string instr, unsigned long Flags = CRYPT_STRING_ANY);
	Handle<std::string> stringToBase64(std::string instr, unsigned long Flags = CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF);
	static LPSTR binaryToLPSTR(const BYTE * pbBinary, DWORD cbBinary);
	static char * convertLPTSTRtoUtf8(LPTSTR strGBK, DWORD CodePage = CP_UTF8);
	static std::string serialNumberToString(_CRYPTOAPI_BLOB * pblobSerialNumber);

	Handle<std::string> readFile(Handle<std::string> in, unsigned long *dwSize);
	void writeBlobToFile(
		CRYPT_DATA_BLOB blobData,
		Handle<std::string> out,
		DataFormat::DATA_FORMAT format,
		DWORD dwFlag = CRYPT_STRING_BASE64HEADER);

	void TimetToFileTime(time_t t, LPFILETIME pft);

	int convert(
		const void * pbSrcData,
		const size_t uiSrcSize,
		BYTE * pbDestDataIn,
		size_t uiDestSizeIn,
		int bFinal);
	static int DecodeBase64Char_int(
		unsigned int ch);
	static int Base64Decode_partial(
		LPCSTR szSrcIn,
		int nSrcLen,
		BYTE *pbDest,
		int *pnDestLen
	);

	static int Base64decode_len(const char *bufcoded);
	static int Base64decode(char *bufplain, const char *bufcoded);

	static std::wstring strToWstr(std::string toConvert);

	static Handle<std::string> FiletimeToStr(const FILETIME& ft);
	static Handle<std::string> SystimeToStr(const SYSTEMTIME& st);
	static Handle<std::string> GeneralizedTimeToStr(const std::string& st);

	static Handle<std::string> getProviderName();

	static void MsgGetParam(HCRYPTMSG hMsg, DWORD dwParamToGet, DWORD dwIdx, CRYPT_DATA_BLOB& result, CSmartBuffer<BYTE>& smartBuffer);
	static void* DecodeObject(LPCSTR structType, BYTE* objData, DWORD objSize, CSmartBuffer<BYTE>& smartBuffer, DWORD dwFlags = 0);
	static void EncodeObject(LPCSTR structType, void* pStructureToEncode, CRYPT_DATA_BLOB& result, CSmartBuffer<BYTE>& smartBuffer);

private:
	BOOL m_bIsFirstPass = true;
	std::string m_strOutBuffer;
};
#endif //!UTILS_TOOLS_H_INCLUDED
