syntax = "proto3";
package data;

import "errorpb.proto";

message DirEntry {
  // Mode is the file's mode. Only the high bits (eg. S_IFDIR)
  // are considered.
  uint32 mode = 1;

  // Name is the basename of the file in the directory.
  string name = 2;

  // sz is the size of the file in bytes.
  uint64 sz = 3;

  bool is_dir = 4;

  // ModTime is the modification time of the file.
  uint64 mod_time = 5;

  uint32 nlink = 6;

  uint64 ino = 7;
}

message FileHandle {
  string token = 1;
  string name = 2;
  uint32 flags = 3;
}

message OpenReq {
  FileHandle file_handle = 1;
}

message OpenResp {
  int64 errno = 1;
  errorpb.Error error = 2;
}

message CreateReq {
  FileHandle file_handle = 1;
  uint32 mode = 2;
}

message CreateResp {
  int64 errno = 1;
  DirEntry entry = 2;
  errorpb.Error error = 3;
}


message FallocateReq {
  FileHandle file_handle = 1;
  uint64 off = 2;
  uint64 size = 3;
  uint32 mode =4;
}

message FallocateResp {
  int64 errno = 1;
  errorpb.Error error = 2;
}


message UnlinkReq {
  string token = 1;
  string name = 2;
}

message UnlinkResp {
  int64 errno = 1;
  errorpb.Error error = 2;
}

message LinkReq {
  string token = 1;
  string old_name = 2;
  string new_name = 3;
}

message  LinkResp {
  int64 errno = 1;
  errorpb.Error error = 2;
}

message SymlinkReq {
  string token = 1;
  string old_name = 2;
  string new_name = 3;
}

message  SymlinkResp {
  int64 errno = 1;
  DirEntry entry = 2;
  errorpb.Error error = 3;
}

message ReadlinkReq {
  string token = 1;
  string name = 2;
}

message  ReadlinkResp {
  int64 errno = 1;
  bytes buf = 2;
  errorpb.Error error = 3;
}

message RenameReq {
  string token = 1;
  string old_name = 2;
  string new_name = 3;
}

message  RenameResp {
  int64 errno = 1;
  errorpb.Error error = 2;
}

message MknodReq {
  string token = 1;
  string name = 2;
  uint32 mode = 3;
  uint32 dev = 4;
}

message MknodResp {
  int64 errno = 1;
  DirEntry entry = 2;
}

message MkdirReq {
  string token = 1;
  string name = 2;
  uint32 mode = 3;
}

message MkdirResp {
  int64 errno = 1;
  DirEntry entry = 2;
}

message RmdirReq {
  string token = 1;
  string name = 2;
}

message RmdirResp {
  int64 errno = 1;
}

message StatfsReq {
  string token = 1;
  string name = 2;
}

message StatfsResp {
  int64 errno = 1;
  uint64 blocks = 2;
  uint64 bfree = 3;
  uint64 bavail = 4;
  uint64 files = 5;
  uint64 ffree = 6;
  uint32 bsize = 7;
  uint32 namelen = 8;
  uint32 frsize = 9;
}

message ReaddirReq {
  string token = 1;
  string name = 2;
}

message ReaddirResp {
  repeated DirEntry entries = 1;
  int64 errno = 2;
}

message LookupReq {
  string token = 1;
  string name = 2;
}

message LookupResp {
  int64 errno = 1;
  DirEntry entry = 2;
}

message SetattrReq {
  string token = 1;
  FileHandle file_handle = 2;
  DirEntry entry = 3;
  bool set_mode = 4;
  bool set_size = 5;
}

message SetattrResp {
  int64 errno = 1;
  DirEntry entry = 2;
  errorpb.Error error = 3;
}

message AccessReq {
  string token = 1;
  string name = 2;
  uint32 mode = 3;
}

message  AccessResp {
  int64 errno = 1;
  errorpb.Error error = 3;
}

message CloseReq {
  FileHandle file_handle = 3;
}

message CloseResp {
  int64 errno = 1;
  errorpb.Error error = 2;
}

message ReadReq {
  FileHandle file_handle = 1;
  int64 off = 2;
  int64 len = 3;
}

message Frame {
  uint64 off = 1;
  uint64 len = 2;
  bytes data = 3;
}

message ReadResp {
  bytes buf = 1;
  repeated Frame frames = 2;
  bool done = 3;
  int64 errno = 4;
  errorpb.Error error = 5;
}

message WriteReq {
  FileHandle file_handle = 1;
  bytes buf = 2;
  int64 off = 3;
}

message WriteResp {
  int64 written = 1;
  int64 errno = 2;
  errorpb.Error error = 3;
}

message FlushReq {
  FileHandle file_handle = 1;
}

message FlushResp {
  int64 errno = 1;
  DirEntry entry = 2;
  errorpb.Error error = 3;
}

message FsyncReq {
  FileHandle file_handle = 1;
}

message FsyncResp {
  int64 errno = 1;
  DirEntry entry = 2;
  errorpb.Error error = 3;
}

message BatchCommandsRequest {
  repeated Request requests = 1;
  repeated uint64 request_ids = 2;

  message Request {
    oneof Cmd {
      ReadReq read = 1;
      WriteReq write = 2;
      FlushReq flush = 3;
      FsyncReq fsync = 4;
      SetattrReq setattr = 5;
      FallocateReq fallocate = 6;
    }
  }
}

message BatchCommandsResponse {
  repeated Response responses = 1;
  repeated uint64 request_ids = 2;
  bool not_mount = 3;

  message Response {
    oneof Cmd {
      ReadResp read = 1;
      WriteResp write = 2;
      FlushResp flush = 3;
      FsyncResp fsync = 4;
      SetattrResp setattr = 5;
      FallocateResp fallocate = 6;
    }
  }
}

service RealmService {
  rpc Create(CreateReq) returns (CreateResp);
  rpc Open(OpenReq) returns (OpenResp);
  rpc Fallocate(FallocateReq) returns (FallocateResp);
  rpc Read(ReadReq) returns (ReadResp);
  rpc Write(WriteReq) returns (WriteResp);
  rpc Flush(FlushReq) returns (FlushResp);
  rpc Unlink(UnlinkReq) returns (UnlinkResp);
  rpc Readdir(ReaddirReq) returns (ReaddirResp);
  rpc Lookup(LookupReq) returns (LookupResp);
  rpc Close(CloseReq) returns (CloseResp);
  rpc Fsync(FsyncReq) returns (FsyncResp);
  rpc Link(LinkReq) returns (LinkResp);
  rpc Symlink(SymlinkReq) returns (SymlinkResp);
  rpc Readlink(ReadlinkReq) returns (ReadlinkResp);
  rpc Rename(RenameReq) returns (RenameResp);
  rpc Mknod(MknodReq) returns (MknodResp);
  rpc Mkdir(MkdirReq) returns (MkdirResp);
  rpc Rmdir(RmdirReq) returns (RmdirResp);
  rpc Statfs(StatfsReq) returns (StatfsResp);
  rpc Setattr(SetattrReq) returns (SetattrResp);
  rpc Access(AccessReq) returns (AccessResp);
  rpc BatchCommands(stream BatchCommandsRequest) returns (stream BatchCommandsResponse);
}
