syntax = "proto3";

package filesystem;

service Filesystem {
    rpc Stat(StatRequest) returns (StatResponse);
    rpc MakeDir(MakeDirRequest) returns (MakeDirResponse);
    rpc Move(MoveRequest) returns (MoveResponse);
    rpc ListDir(ListDirRequest) returns (ListDirResponse);
    rpc Remove(RemoveRequest) returns (RemoveResponse);

    rpc WatchDir(WatchDirRequest) returns (stream WatchDirResponse);

    // Non-streaming versions of WatchDir
    rpc CreateWatcher(CreateWatcherRequest) returns (CreateWatcherResponse);
    rpc GetWatcherEvents(GetWatcherEventsRequest) returns (GetWatcherEventsResponse);
    rpc RemoveWatcher(RemoveWatcherRequest) returns (RemoveWatcherResponse);
}

message MoveRequest {
    string source = 1;
    string destination = 2;
}

message MoveResponse {
    EntryInfo entry = 1;
}

message MakeDirRequest {
    string path = 1;
}

message MakeDirResponse {
    EntryInfo entry = 1;
}

message RemoveRequest {
    string path = 1;
}

message RemoveResponse {}

message StatRequest {
    string path = 1;
}

message StatResponse {
    EntryInfo entry = 1;
}

message EntryInfo {
    string name = 1;
    FileType type = 2;
    string path = 3;
}

enum FileType {
    FILE_TYPE_UNSPECIFIED = 0;
    FILE_TYPE_FILE = 1;
    FILE_TYPE_DIRECTORY = 2;
}

message ListDirRequest {
    string path = 1;
}

message ListDirResponse {
    repeated EntryInfo entries = 1;
}

message WatchDirRequest {
    string path = 1;
}

message FilesystemEvent {
    string name = 1;
    EventType type = 2;
}

message WatchDirResponse {
    oneof event {
        StartEvent start = 1;
        FilesystemEvent filesystem = 2;
        KeepAlive keepalive = 3;
    }

    message StartEvent {}

    message KeepAlive {}
}

message CreateWatcherRequest {
    string path = 1;
}

message CreateWatcherResponse {
    string watcher_id = 1;
}

message GetWatcherEventsRequest {
    string watcher_id = 1;
}

message GetWatcherEventsResponse {
    repeated FilesystemEvent events = 1;
}

message RemoveWatcherRequest {
      string watcher_id = 1;
}

message RemoveWatcherResponse {}

enum EventType {
    EVENT_TYPE_UNSPECIFIED = 0;
    EVENT_TYPE_CREATE = 1;
    EVENT_TYPE_WRITE = 2;
    EVENT_TYPE_REMOVE = 3;
    EVENT_TYPE_RENAME = 4;
    EVENT_TYPE_CHMOD = 5;
}
