/**
 * Communication protocol between FUSE client and the server.
 * @author Krzysztof Trzepla
 * @copyright (C) 2015 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in
 * 'LICENSE.txt'
 */

syntax = "proto2";
package one.clproto;

import "common_messages.proto";

enum FileType {
    REG = 1; // regular file
    DIR = 2; // directory
    LNK = 3; // symbolic link
}

enum HelperMode {
    AUTO         = 1; // automatic helper mode detection
    FORCE_PROXY  = 2; // return proxy io helper or error
    FORCE_DIRECT = 3; // return direct io helper or error
}

// Generic FUSE client request
message FuseRequest {
    oneof fuse_request { // list of all FUSE client requests
        ResolveGuid resolve_guid = 1;
        GetHelperParams get_helper_params = 2;
        CreateStorageTestFile create_storage_test_file = 3;
        VerifyStorageTestFile verify_storage_test_file = 4;
        FileRequest file_request = 5;
    }
}

message ResolveGuid {
    required bytes path = 1;
}

message GetHelperParams {
    required bytes storage_id       = 1;
    required bytes space_id         = 2;
    optional HelperMode helper_mode = 3;
}

message CreateStorageTestFile {
    required bytes storage_id = 1;
    required bytes file_uuid  = 2;
}

message VerifyStorageTestFile {
    required bytes storage_id   = 1;
    required bytes space_id     = 2;
    required bytes file_id      = 3;
    required bytes file_content = 4;
}

// Generic FUSE client file request
message FileRequest {
    required bytes context_guid = 1;
    optional bool extended_direct_io = 2;

    oneof file_request { // list of all FUSE client file requests
        GetFileAttr get_file_attr = 3;
        GetChildAttr get_child_attr = 4;
        GetFileChildren get_file_children = 5;
        CreateDir create_dir = 6;
        DeleteFile delete_file = 7;
        UpdateTimes update_times = 8;
        ChangeMode change_mode = 9;
        Rename rename = 10;
        CreateFile create_file = 11;
        MakeFile make_file = 12;
        OpenFile open_file = 13;
        GetFileLocation get_file_location = 14;
        Release release = 15;
        Truncate truncate = 16;
        SynchronizeBlock synchronize_block = 17;
        SynchronizeBlockAndComputeChecksum synchronize_block_and_compute_checksum = 18;
        GetXattr get_xattr = 19;
        SetXattr set_xattr = 20;
        RemoveXattr remove_xattr = 21;
        ListXattr list_xattr = 22;
        FSync fsync = 23;
        GetFileChildrenAttrs get_file_children_attrs = 24;
        StorageFileCreated storage_file_created = 25;
        OpenFileWithExtendedInfo open_file_with_extended_info = 26;
        BlockSynchronizationRequest block_synchronization_request = 27;
    }
}

message GetFileAttr {
}

message GetChildAttr {
    required bytes name = 1;
}

message GetFileChildren {
    required int32 offset = 1;
    required int32 size = 2;
    optional bytes index_token = 3;
}

message GetFileChildrenAttrs {
    required int32 offset = 1;
    required int32 size = 2;
    optional bytes index_token = 3;
}

message CreateDir {
    required bytes name = 1;
    required uint32 mode = 2;
}

message DeleteFile {
    optional bool  silent = 1;
}

message UpdateTimes {
    optional int64 atime = 1;
    optional int64 mtime = 2;
    optional int64 ctime = 3;
}

message ChangeMode {
    required int32 mode = 1;
}

message Rename {
    required bytes target_parent_uuid = 1;
    required bytes target_name = 2;
}

message CreateFile {
    required bytes name = 1;
    required uint32 mode = 2;
    required OpenFlag flag = 3;
}

message MakeFile {
    required bytes name = 1;
    required uint32 mode = 2;
}

message OpenFile {
    required OpenFlag flag = 1;
}

message OpenFileWithExtendedInfo {
    required OpenFlag flag = 1;
}

message GetFileLocation {
}

message Release {
    required bytes handle_id = 1;
}

message Truncate {
    required int64 size = 1;
}

message SynchronizeBlock {
    required FileBlock block    = 1;
    optional bool      prefetch = 2;
    optional int32     priority = 3;
}

message SynchronizeBlockAndComputeChecksum {
    required FileBlock block = 1;
    optional bool      prefetch = 2;
    optional int32     priority = 3;
}

message BlockSynchronizationRequest {
    required FileBlock block    = 1;
    optional bool      prefetch = 2;
    optional int32     priority = 3;
}

message Xattr {
    required bytes name = 1;
    required bytes value = 2;
}

message GetXattr {
    required bytes name = 1;
    optional bool inherited = 2;
}

message SetXattr {
    required Xattr xattr = 1;
    optional bool create = 2;
    optional bool replace = 3;
}

message RemoveXattr {
    required bytes name = 1;
}

message ListXattr {
    optional bool inherited = 1;
    optional bool show_internal = 2;
}

message FSync {
    optional bool data_only = 1;
    optional bytes handle_id = 2;
}

message StorageFileCreated {
}

// Generic FUSE client response
message FuseResponse {
    required Status status = 1;

    oneof fuse_response { // list of all FUSE client responses
        FileAttr file_attr = 2;
        FileChildren file_children = 3;
        FileLocation file_location = 4;
        HelperParams helper_params = 5;
        StorageTestFile storage_test_file = 6;
        Dir dir = 7;
        SyncResponse sync_response = 8;
        FileRenamed file_renamed = 9;
        FileCreated file_created = 10;
        FileOpened file_opened = 11;
        Uuid uuid = 12;
        Xattr xattr = 13;
        XattrList xattr_list = 14;
        FileChildrenAttrs file_children_attrs = 15;
        FileLocationChanged file_location_changed = 16;
        FileOpenedExtended file_opened_extended = 17;
    }
}

message FileAttr {
    required bytes uuid = 1;
    required bytes name = 2;
    required int32 mode = 3;
    required int32 uid = 4;
    required int32 gid = 5;
    required int64 atime = 6;
    required int64 mtime = 7;
    required int64 ctime = 8;
    required FileType type = 9;
    optional int64 size = 10;
    repeated bytes shares = 11;
    required bytes provider_id = 12;
    required bytes owner_id = 13;
    optional bytes parent_uuid = 14;
}

message FileChildren {
    repeated ChildLink child_links = 1;
    optional bytes index_token = 2;
    optional bool is_last = 3;
}

message FileChildrenAttrs {
    repeated FileAttr child_attrs = 1;
    optional bytes index_token = 2;
    optional bool is_last = 3;
}

message FileLocationChanged {
    required FileLocation file_location = 1;
    optional uint64 change_beg_offset = 2;
    optional uint64 change_end_offset = 3;
}

message FileLocation {
    required bytes uuid = 1;
    required bytes provider_id = 2;
    required bytes space_id = 3;
    required bytes storage_id = 4;
    required bytes file_id = 5;
    repeated FileBlock blocks = 6;
    required uint64 version = 7;
}

message FileCreated {
    required bytes handle_id = 1;
    required FileAttr file_attr = 2;
    required FileLocation file_location = 3;
}

message FileOpened {
    required bytes handle_id = 1;
}

message FileOpenedExtended {
    required bytes handle_id = 1;
    required bytes provider_id = 2;
    required bytes file_id = 3;
    required bytes storage_id = 4;
}

message HelperArg {
    required string key = 1;
    required string value = 2;
}

message HelperParams {
    required bytes helper_name = 1;
    repeated HelperArg helper_args = 2;
    optional bool extended_direct_io = 3;
}

message StorageTestFile {
    required HelperParams helper_params = 1;
    required bytes        space_id      = 2;
    required bytes        file_id       = 3;
    required bytes        file_content  = 4;
}

message SyncResponse {
    required bytes checksum = 1;
    required FileLocationChanged file_location_changed = 2;
}

message FileRenamed {
    required bytes new_uuid = 1;
    repeated FileRenamedEntry child_entries = 2; // entries for children of
                                                 // renamed file
}

message Uuid {
    required bytes uuid = 1;
}

message XattrList {
    repeated bytes names = 1;
}
