#ifndef fuse_symlinks_H
#define fuse_symlinks_H
/*
 * Copyright 2022-2023, Your Name <your@email.address>
 */


/* Genode includes */
#include <vfs/vfs_handle.h>


struct Symlink_vfs_handle : public Vfs::Vfs_handle
{
	private:

		static const int debug = 0;
		
		//xx Genode has 3 different definitions of MAX_PATH_LEN, from 256 to 1024 -- using
		//xx the middle-of-the-road for now (Vfs::'s one is 512 bytes)
		///ToDo: which of the three MAX_PATH_LEN should I use ?
		
			String<Vfs::MAX_PATH_LEN> _path;

	public:

		Symlink_vfs_handle(Vfs::Directory_service &ds,
		                Vfs::File_io_service   &fs,
		                Genode::Allocator &alloc,
		                Directory::Path path)
		:	Vfs_handle(ds, fs, alloc, 0)
			,_path(path)
		{
		}

		Vfs::File_io_service::Read_result
			read(char *dest, Vfs::file_size len, size_t &out_count)
		{
			if( debug )
				Genode::log("   symlink.read file=", _path);

			using namespace Vfs;
			
			// T0
			int res = Fuse::fuse()->op.readlink( _path.string(), dest, len );
			if( debug )
				Genode::log( "SYM-Read res=", res );

			// readlink() returns 0 for success, non-zero on failure:
			if( res != 0 )
				return File_io_service::READ_ERR_INVALID;
			
			Genode::Cstring bounded( dest, len );
			out_count = bounded.length();//_d_: Genode::strlen( dest, len);//maybeAddMaxLenHere );//_d_!! : len;
			
			if( debug )
				Genode::log( "   ----- symlink.read(): assigning out_count=", out_count, " versus strlen=", Genode::strlen(dest) );
			
			return File_io_service::READ_OK;
		}

		Vfs::File_io_service::Write_result
			write(char const *src, Vfs::file_size len, size_t &out_count)
		{
			if( debug )
				Genode::log("   symlink.write file=", _path, " buf=", src);
			
			using namespace Vfs;
			
			if (len > MAX_PATH_LEN)
				return File_io_service::WRITE_ERR_INVALID;
	
			int res = Fuse::fuse()->op.symlink( src, _path.string() );////, len );
			if( debug )
				Genode::log( "SYM-WR res=", res );
			// seems to return -2 if the symlink already exists...
			// uh actually, returns -17 ?
			
			if( res != 0 )
				return File_io_service::WRITE_ERR_INVALID;
			
			out_count = len;
			return Vfs::File_io_service::WRITE_OK;
		}
};


#endif // fuse_symlinks_H

