
#ifndef DKUTIL_CRYPTOGRAPH_FILE_TO_FILE_HPP
#define DKUTIL_CRYPTOGRAPH_FILE_TO_FILE_HPP

#include <dkutil/cryptograph/arcfour.hpp>
#include <dkutil/cryptograph/blowfish.hpp>
#include <dkutil/cryptograph/hc256.hpp>
#include <dkutil/cryptograph/snow2.hpp>
#include <dkutil/output/logger.hpp>
#include <dkutil/boost/shared_ptr.hpp>
#include <dkutil/filesystem/big_filestream.hpp>


namespace dkutil{
/*
template<class T>
struct cryptograph_stream_action{
	typedef typename T policy_type;
	policy_type mA;
	
	bool operator()(uint8 *pd,size_t size){
			
};
	*/
template<class T>
class CCryptographFileConverter : public COutputLog_Base{
public:
	typedef typename T policy_type;
	///file stream type
	typedef CBigFileStream fs_type;
	typedef boost::shared_ptr<IStreamConvert> convert_ptr;
private:
	 convert_ptr mA;

public:
	/*
	class crypto_functor{
		policy_type *mp;
		fs_type *mfp;
	public:
		crypto_functor(policy_type *p,fs_type *fp) : mp(p),mfp(fp){}
		void operator()(uint8 *a,size_t size)
		{
			mp->convert(

		}

	};*/
	CCryptographFileConverter(){}
	~CCryptographFileConverter(){}

	bool convert(const PasswordOption &pass,
		parm_string destfile,parm_string srcfile,
		bool is_overwrite = false,size_t inner_buffer_size = 1024 * 512)
	{
		if(false==is_overwrite && FileAndFolderExist(destfile))
		{
			setLog(destfile);
			setErrorMessageCode(edkErrorAlreadyExists);
			return false;
		}
		fs_type fr,fw;
		if(false==fr.reset(srcfile,read_mode | binary_mode)){
			setLog(srcfile);
			setErrorMessageCode(edkErrorOpenFailed);
			//setLog("をread modeでオープンできませんでした。");
			return false;
		}
		if(false==fw.reset(destfile,write_mode | binary_mode)){
			setLog(destfile);
			setErrorMessageCode(edkErrorOpenFailed);
			return false;
		}
		mA.reset(new policy_type(pass,inner_buffer_size));

		IStreamConvert::convert_result r;
		bool res =mA->convert(&fw,&fr,&r);
		//r.converted_size
		return res;
		//div_read_each_functor<big_filestream,crypto_functor>


		//div_read_each_functor<

	}

};


inline bool ArcfourEncodeFileToFile(
		const PasswordOption &pass,
	path_string_ref destfile,path_string_ref srcfile,
	bool overwrite = false,std::ostream *pos = NULL,size_t inner_buffer_size = 1024 * 512)
{
	CCryptographFileConverter<CArcfourConvertStream> a;
	a.set_ostream(pos);
	return a.convert(pass,destfile,srcfile,overwrite,inner_buffer_size);
}

inline bool ArcfourDecodeFileToFile(
		const PasswordOption &pass,
	path_string_ref destfile,path_string_ref srcfile,
	bool overwrite = false,std::ostream *pos = NULL,size_t inner_buffer_size = 1024 * 512)
{
	CCryptographFileConverter<CArcfourConvertStream> a;
	a.set_ostream(pos);
	return a.convert(pass,destfile,srcfile,overwrite,inner_buffer_size);
}

/*
inline bool HC256EncodeFileToFile(
		const PasswordOption &pass,
	path_string_ref destfile,path_string_ref srcfile,
	bool overwrite = false,std::ostream *pos = NULL,size_t inner_buffer_size = 1024 * 512)
{
	CCryptographFileConverter<CHC256EncodeStream> a;
	a.set_ostream(pos);
	return a.convert(pass,destfile,srcfile,overwrite,inner_buffer_size);
}

inline bool HC256DecodeFileToFile(
	const PasswordOption &pass,
	path_string_ref destfile,path_string_ref srcfile,
	bool overwrite = false,std::ostream *pos = NULL,size_t inner_buffer_size = 1024 * 512)
{
	CCryptographFileConverter<CHC256DecodeStream> a;
	a.set_ostream(pos);
	return a.convert(pass,destfile,srcfile,overwrite,inner_buffer_size);
}*/

}//end of dkutil namespace





#endif