syntax = "proto3";

import "common.proto";

package file;


message File {
	bool writable = 1;
	bool is_versioned = 2;
	string name = 3;
	bool is_new = 4;
	// impl is a reference to object with methods of either
	// ReadonlyFile or WritableFile
	common.ObjectReference impl = 5;
	bool is_synced = 6;
}


message SyncStatusMsg {
	string state = 1;
	SyncVersionsBranchMsg local = 2;
	SyncVersionsBranchMsg synced = 3;
	SyncVersionsBranchMsg remote = 4;
	common.BooleanValue exists_in_synced_parent = 5;
	UploadingStateMsg uploading = 6;
}

message SyncVersionsBranchMsg {
	common.UInt64Value latest = 1;
	repeated uint64 archived = 2;
	common.BooleanValue is_archived = 3;
}

message UploadingStateMsg {
	uint64 local_version = 1;
	uint64 remote_version = 2;
	uint64 bytes_left_to_upload = 3;
	bool upload_started = 4;
}

// ==== ReadonlyFile referable as impl object ====

// --- ReadonlyFile.stat ---
// Request body is empty
// Reply body is StatsMsg
message StatsMsg {
	common.BooleanValue is_file = 1;
	common.BooleanValue is_folder = 2;
	common.BooleanValue is_link = 3;
	bool writable = 4;
	common.UInt64Value size = 5;
	common.UInt64Value mtime = 6;
	common.UInt64Value ctime = 7;
	common.UInt64Value version = 8;
	SyncStatusMsg sync = 9;
}

// --- ReadonlyFile.getXAttr ---
// Reply body is XAttrValue
message GetXAttrRequestBody {
	string xa_name = 1;
}

message XAttrValue {
	common.StringValue str = 1;
	common.StringValue json = 2;
	common.BytesValue bytes = 3;
}

// --- ReadonlyFile.listXAttrs ---
// Request body is empty
// Reply body is common.StringArrayValue

// --- ReadonlyFile.readBytes ---
message ReadBytesRequestBody {
	common.UInt64Value start = 1;
	common.UInt64Value end = 2;
}
message ReadBytesReplyBody {
	common.BytesValue bytes = 1;
}

// --- ReadonlyFile.readTxt ---
// Request body is empty
// Reply body contains utf8 bytes of a string

// --- ReadonlyFile.readJSON ---
// Request body is empty
// Reply body contains utf8 bytes of a json string

// --- ReadonlyFile.getByteSource ---
// Request body is empty
// Reply body is common.ObjectReference to FileByteSource.

// --- ReadonlyFile.watch ---
// Its an observable call, and initial request is empty.
// Observer expects FileEvent in next.

message FileEventMsg {
	string type = 1;
	string path = 2;
	common.StringValue src = 3;
	common.UInt64Value new_version = 4;
	common.UInt64Value removed_arch_ver = 5;
	common.UInt64Value archived_version = 6;
}


// ==== ReadonlyFileVersionedAPI referable object ====

message VersionedReadFlags {
	common.UInt64Value archived_version = 1;
	common.UInt64Value remote_version = 2;
}

message RequestWithVersionedReadFlags {
	VersionedReadFlags flags = 1;
}

// --- ReadonlyFileVersionedAPI.stat ---
// Request body is RequestWithVersionedReadFlags
// Reply body is StatsMsg

// --- ReadonlyFileVersionedAPI.getXAttr ---
message VersionedGetXAttrRequestBody {
	string xa_name = 1;
	VersionedReadFlags flags = 2;
}
message VersionedGetXAttrReplyBody {
	uint64 version = 1;
	common.StringValue str = 2;
	common.StringValue json = 3;
	common.BytesValue bytes = 4;
}

// --- ReadonlyFileVersionedAPI.listXAttrs ---
// Request body is RequestWithVersionedReadFlags
message VersionedListXAttrsReplyBody {
	uint64 version = 1;
	repeated string xa_names = 2;
}

// --- ReadonlyFileVersionedAPI.readBytes ---
message VersionedReadBytesRequestBody {
	common.UInt64Value start = 1;
	common.UInt64Value end = 2;
	VersionedReadFlags flags = 10;
}
message VersionedReadBytesReplyBody {
	uint64 version = 1;
	common.BytesValue bytes = 2;
}

// --- ReadonlyFileVersionedAPI.readTxt ---
// Request body is RequestWithVersionedReadFlags
message VersionedReadTxtReplyBody {
	uint64 version = 1;
	string txt = 2;
}

// --- ReadonlyFileVersionedAPI.readJSON ---
// Request body is RequestWithVersionedReadFlags
message VersionedReadJsonReplyBody {
	uint64 version = 1;
	string json = 2;
}

// --- ReadonlyFileVersionedAPI.getByteSource ---
// Request body is RequestWithVersionedReadFlags
message VersionedGetByteSourceReplyBody {
	uint64 version = 1;
	// src is a reference to FileByteSource
	common.ObjectReference src = 2;
}

// --- ReadonlyFileVersionedAPI.listVersions ---
// Request body is RequestWithVersionedReadFlags
message ListVersionsReplyBody {
	common.UInt64Value current = 1;
	repeated uint64 archived = 2;
}


// ==== WritableFile referable as impl object (extends ReadonlyFile) ====

// --- WritableFile.updateXAttrs ---
// Reply has only status and body is empty
message UpdateXAttrsRequestBody {
	XAttrsChanges changes = 1;
}

message NameAndXAttrValue {
	string xa_name = 1;
	common.StringValue str = 2;
	common.StringValue json = 3;
	common.BytesValue bytes = 4;
}

message XAttrsChanges {
	repeated NameAndXAttrValue set = 1;
	repeated string remove = 2;
}

// --- WritableFile.writeBytes ---
// Reply has only status and body is empty
message WriteBytesRequestBody {
	bytes bytes = 1;
}

// --- WritableFile.writeTxt ---
// Reply has only status and body is empty
message WriteTxtRequestBody {
	string txt = 1;
}

// --- WritableFile.writeJSON ---
// Reply has only status and body is empty
message WriteJsonRequestBody {
	string json = 1;
}

// --- WritableFile.getByteSink ---
// Reply body is common.ObjectReference to FileByteSink.
message GetByteSinkRequestBody {
	common.BooleanValue truncate_file = 1;
}

// --- WritableFile.copy ---
// Reply has only status and body is empty
message CopyRequestBody {
	// file is a reference to writable file
	common.ObjectReference file = 1;
}


// ==== WritableFileVersionedAPI referable object ====

// --- WritableFileVersionedAPI.updateXAttrs ---
// Request body is UpdateXAttrsRequestBody
// Reply body is common.UInt64Value

// --- WritableFileVersionedAPI.writeBytes ---
// Request body is WriteBytesRequestBody
// Reply body is common.UInt64Value

// --- WritableFileVersionedAPI.writeTxt ---
// Request body is WriteTxtRequestBody
// Reply body is common.UInt64Value

// --- WritableFileVersionedAPI.writeJSON ---
// Request body is WriteJsonRequestBody
// Reply body is common.UInt64Value

// --- WritableFileVersionedAPI.getByteSink ---
message VersionedGetByteSinkRequestBody {
	common.BooleanValue truncate_file = 1;
	common.UInt64Value current_version = 2;
}
message VersionedGetByteSinkReplyBody {
	uint64 version = 1;
	// sink is a reference to FileByteSink
	common.ObjectReference sink = 2;
}

// --- WritableFileVersionedAPI.copy ---
// Request body is CopyRequestBody
// Reply body is common.UInt64Value

// --- WritableFileVersionedAPI.archiveCurrent ---
// Reply body is common.UInt64Value
message ArchiveCurrentRequestBody {
	common.UInt64Value version = 1;
}


// ==== ReadonlyFileSyncAPI referable object ====

// --- ReadonlyFileSyncAPI.status ---
// Request body is common.BooleanValue
// Reply body is SyncStatusMsg

// --- ReadonlyFileSyncAPI.isRemoteVersionOnDisk ---
message FileSyncIsOnDiskRequestBody {
	uint64 version = 1;
}
message FileSyncIsOnDiskReplyBody {
	string status = 1;
}

// --- ReadonlyFileSyncAPI.download ---
// Reply has only status and body is empty
message FileSyncDownloadRequestBody {
	uint64 version = 1;
}

// --- ReadonlyFileSyncAPI.adoptRemote ---
// Reply has only status and body is empty
message AdoptRemoteRequestBody {
	OptionsToAdopteRemote opts = 1;
}

message OptionsToAdopteRemote {
	common.BooleanValue drop_local_ver = 1;
	common.UInt64Value remote_version = 2;
}


// ==== WritableFileSyncAPI referable object ====

// --- WritableFileSyncAPI.upload ---
// Reply body is common.UInt64Value
message FileSyncUploadRequestBody {
	OptionsToUploadLocal opts = 1;
}
message FileSyncUploadReplyBody {
	common.UInt64Value uploaded_version = 1;
}

message OptionsToUploadLocal {
	common.UInt64Value local_version = 1;
	common.UInt64Value upload_version = 2;
}
