#ifndef FZ_TVFS_FILE_HPP
#define FZ_TVFS_FILE_HPP

#include <libfilezilla/file.hpp>
#include "../util/copies_counter.hpp"
#include "../badge.hpp"
#include "../file_interface.hpp"

namespace fz::tvfs
{

class engine;

class file_holder: public file_interface
{
public:
	file_holder() = default;
	file_holder(std::unique_ptr<file_interface> &&file, const util::copies_counter &counter, std::string path, badge<engine>)
		: file_(std::move(file))
		, counter_(counter)
		, path_(std::move(path))
	{
	}

	friend void swap(file_holder &lhs, file_holder &rhs) noexcept
	{
		using std::swap;

		swap(lhs.file_, rhs.file_);
		swap(lhs.counter_, rhs.counter_);
		swap(lhs.path_, rhs.path_);
	}

	file_holder(file_holder &&rhs)
		: file_holder()
	{
		swap(*this, rhs);
	}

	file_holder &operator=(file_holder &&rhs)
	{
		file_holder copy{std::move(rhs)};
		swap(*this, copy);
		return *this;
	}

	file_holder(const file_holder &) = delete;
	file_holder &operator=(const file_holder &) = delete;

	int64_t size() const override
	{
		return file_->size();
	}

	int64_t seek(int64_t offset, file::seek_mode m) override
	{
		return file_->seek(offset, m);
	}

	bool truncate() override
	{
		return file_->truncate();
	}

	rwresult read(void *buf, size_t count) override
	{
		return file_->read(buf, count);
	}

	rwresult write(const void *buf, size_t count) override
	{
		return file_->write(buf, count);
	}

	bool set_modification_time(const datetime &t) override
	{
		return file_->set_modification_time(t);
	}

	datetime get_modification_time() override
	{
		return file_->get_modification_time();
	}

	operator bool() const
	{
		return bool(file_);
	}

	const std::string &path() const
	{
		return path_;
	}

private:
	std::unique_ptr<file_interface> file_;
	util::copies_counter counter_;
	std::string path_;
};

}
#endif // FZ_TVFS_FILE_HPP
