#ifndef FSFILE_H
#define FSFILE_H

#include "amisc.h"
#include "async.h"
#include "arpc.h"
#include "nfsserv.h"
#include "tagged_blockdbc.h"
#include "fs.h"

class fs;


#define TYPE_FATTR "fattr"
#define TYPE_FDATA "fdata"

class fsfile 
{
public:
  fsfile(fs *ifs, str fileid);
  str get_fileid();
  void get_fattr(callback<void, bool, fattr3>::ref cb);
  void set_fattr(fattr3 fattr, callback<void, bool, fattr3>::ref cb);
  void read(uint64 offset, uint64 length,
            callback<void, bool, str>::ref cb);
  void write(uint64 offset, uint64 length, str data,
             callback<void, bool>::ref cb);
  void set_size(uint64 size, callback<void, bool>::ref cb);
  void create(fattr3 newfa, callback<void, int, fattr3>::ref cb);
  
private:
  fs *ffs;
  ptr<tagged_blockdbc> bdb;
  str fileid;

  void get_fattr_on_bdbget(callback<void, bool, fattr3>::ref cb,
                           bool ok, str val);
  void set_fattr_on_bdbput(callback<void, bool, fattr3>::ref cb,
                           fattr3 fa, bool ok);
  void read_on_get_fattr(uint64 offset, uint64 length,
                         callback<void, bool, str>::ref cb,
                         bool ok, fattr3 fa);
  void read_on_bdbget(uint64 offset, uint64 length,
                      callback<void, bool, str>::ref cb, bool ok,
                      str data);
  void write_on_get_fattr(uint64 offset, uint64 length, str data,
                          callback<void, bool>::ref cb,
                          bool ok, fattr3 fa);
  void write_on_bdb_get(uint64 offset, uint64 length, str data,
                        callback<void, bool>::ref cb,
                        fattr3 fa, bool ok, str filedata);
  void write_on_set_fattr(callback<void, bool>::ref cb, str newdata,
                          bool ok, fattr3 fa);
  void write_on_bdb_put(callback<void, bool>::ref cb, bool ok);
  void set_size_on_get_fattr(uint64 size, callback<void, bool>::ref cb,
                             bool ok, fattr3 fa);
  void set_size_on_set_fattr(uint64 size, callback<void, bool>::ref cb,
                             bool ok, fattr3 fa);
  void create_on_get_fattr(fattr3 newfa, callback<void, int, fattr3>::ref cb,
                           bool ok, fattr3 oldfa);
  void create_on_set_fattr(callback<void, int, fattr3>::ref cb,
                            bool ok, fattr3 setfa);
  void create_on_bdb_put(callback<void, int, fattr3>::ref cb,
                         fattr3 setfa, bool ok);
      
};


#endif // FSFILE_H
