#include "res/package_path.h"
#include <vector>
#include <fstream>
#include <variant>
namespace engineapi {
	using std::vector;
	enum class FILE_OP
	{
		READ,
		WRITE,
		APPEND,
		NONE
	};
	class FileHandle : PackagePath{
	protected:
		uint32_t flag{0};
		FILE_OP op{ FILE_OP::NONE};
		std::variant<std::ifstream, std::ofstream, nullptr_t> vfile{nullptr};
	public:
		using PackagePath::PackagePath;
		FileHandle(const PackagePath& path) : PackagePath(path){}
		uint32_t Flag() {
			return flag;
		}
		operator bool() {
			return flag & File_Success;
		}
		std::ifstream& Reader() {
			return std::get<std::ifstream>(vfile);
		}
		std::ofstream& Writer() {
			return std::get<std::ofstream>(vfile);
		}
		FileHandle& Open(FILE_OP op, bool is_binarry = false);
		int Read(void* data, int size);
		template<typename T = vector<char>>
		T ReadAll() {
			Reader().seekg(0);
			return ReadLeft<T>();
		}
		template<typename T = vector<char>>
		T ReadLeft();
		string ReadUntil(const string& token);
		vector<char> ReadUntil(const vector<char>& token);
		void Write(const char* data, size_t size);
	};
	template<typename T>
	inline T FileHandle::ReadLeft()
	{
		auto& fi = Reader();
		size_t cur = fi.tellg();
		fi.seekg(0, std::ios::end);
		size_t size = (size_t)fi.tellg() - cur;
		fi.seekg(cur);
		T data;
		data.resize(size, '\0');
		fi.read(data.data(), size);
		// 检查实际读取的字节数
		size_t read = (size_t)fi.gcount();
		if (read != size) {
			data.resize(read);
		}
		return data;
	}
}