syntax = "proto3";

package com.owncloud.ocis.settings.v0;

option go_package = "github.com/owncloud/ocis/settings/pkg/proto/v0;proto";

import "google/api/annotations.proto";
import "google/protobuf/empty.proto";

import "protoc-gen-openapiv2/options/annotations.proto";

option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
  info: {
    title: "ownCloud Infinite Scale settings";
    version: "1.0.0";
    contact: {
      name: "ownCloud GmbH";
      url: "https://github.com/owncloud/ocis";
      email: "support@owncloud.com";
    };
    license: {
      name: "Apache-2.0";
      url: "https://github.com/owncloud/ocis/blob/master/LICENSE";
    };
  };
  schemes: HTTP;
  schemes: HTTPS;
  consumes: "application/json";
  produces: "application/json";
  external_docs: {
    description: "Developer Manual";
    url: "https://owncloud.dev/extensions/settings/";
  };
};

service BundleService {
  rpc SaveBundle(SaveBundleRequest) returns (SaveBundleResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/bundle-save",
      body: "*"
    };
  }
  rpc GetBundle(GetBundleRequest) returns (GetBundleResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/bundle-get",
      body: "*"
    };
  }
  rpc ListBundles(ListBundlesRequest) returns (ListBundlesResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/bundles-list",
      body: "*"
    };
  }
  rpc AddSettingToBundle(AddSettingToBundleRequest) returns (AddSettingToBundleResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/bundles-add-setting",
      body: "*"
    };
  }
  rpc RemoveSettingFromBundle(RemoveSettingFromBundleRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/api/v0/settings/bundles-remove-setting",
      body: "*"
    };
  }
}

service ValueService {
  rpc SaveValue(SaveValueRequest) returns (SaveValueResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/values-save",
      body: "*"
    };
  }
  rpc GetValue(GetValueRequest) returns (GetValueResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/values-get",
      body: "*"
    };
  }
  rpc ListValues(ListValuesRequest) returns (ListValuesResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/values-list",
      body: "*"
    };
  }
  rpc GetValueByUniqueIdentifiers(GetValueByUniqueIdentifiersRequest) returns (GetValueResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/values-get-by-unique-identifiers",
      body: "*"
    };
  }
}

service RoleService {
  rpc ListRoles(ListBundlesRequest) returns (ListBundlesResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/roles-list",
      body: "*"
    };
  }
  rpc ListRoleAssignments(ListRoleAssignmentsRequest) returns (ListRoleAssignmentsResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/assignments-list",
      body: "*"
    };
  }
  rpc AssignRoleToUser(AssignRoleToUserRequest) returns (AssignRoleToUserResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/assignments-add",
      body: "*"
    };
  }
  rpc RemoveRoleFromUser(RemoveRoleFromUserRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/api/v0/settings/assignments-remove",
      body: "*"
    };
  }
}

service PermissionService {
  rpc ListPermissionsByResource(ListPermissionsByResourceRequest) returns (ListPermissionsByResourceResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/permissions-list-by-resource",
      body: "*"
    };
  }
  rpc GetPermissionByID(GetPermissionByIDRequest) returns (GetPermissionByIDResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/permissions-get-by-id",
      body: "*"
    };
  }
}

// ---
// requests and responses for settings bundles
// ---
message SaveBundleRequest {
  Bundle bundle = 1;
}

message SaveBundleResponse {
  Bundle bundle = 1;
}

message GetBundleRequest {
  string bundle_id = 1;
}

message GetBundleResponse {
  Bundle bundle = 1;
}

message ListBundlesRequest {
  repeated string bundle_ids = 1;
}

message ListBundlesResponse {
  repeated Bundle bundles = 1;
}

message AddSettingToBundleRequest {
  string bundle_id = 1;
  Setting setting = 2;
}

message AddSettingToBundleResponse {
  Setting setting = 1;
}

message RemoveSettingFromBundleRequest {
  string bundle_id = 1;
  string setting_id = 2;
}

// ---
// requests and responses for settings values
// ---

message SaveValueRequest {
  Value value = 1;
}

message SaveValueResponse {
  ValueWithIdentifier value = 1;
}

message GetValueRequest {
  string id = 1;
}

message GetValueResponse {
  ValueWithIdentifier value = 1;
}

message ListValuesRequest {
  string bundle_id = 1;
  string account_uuid = 2;
}

message ListValuesResponse {
  repeated ValueWithIdentifier values = 1;
}

message GetValueByUniqueIdentifiersRequest{
  string account_uuid = 1;
  string setting_id = 2;
}

message ValueWithIdentifier {
  Identifier identifier = 1;
  Value value = 2;
}

message Identifier {
  string extension = 1;
  string bundle = 2;
  string setting = 3;
}

// --
// requests and responses for role assignments
// ---

message ListRoleAssignmentsRequest {
  string account_uuid = 1;
}

message ListRoleAssignmentsResponse {
  repeated UserRoleAssignment assignments = 1;
}

message AssignRoleToUserRequest {
  string account_uuid = 1;
  // the role_id is a bundle_id internally
  string role_id = 2;
}

message AssignRoleToUserResponse {
  UserRoleAssignment assignment = 1;
}

message RemoveRoleFromUserRequest {
  string id = 1;
}

message UserRoleAssignment {
  // id is generated upon saving the assignment
  string id = 1;
  string account_uuid = 2;
  // the role_id is a bundle_id internally
  string role_id = 3;
}

// --
// requests and responses for permissions
// ---

message ListPermissionsByResourceRequest {
  Resource resource = 1;
}

message ListPermissionsByResourceResponse {
  repeated Permission permissions = 1;
}

message GetPermissionByIDRequest {
  string permission_id = 1;
}

message GetPermissionByIDResponse {
  Permission permission = 1;
}

// ---
// resource payloads
// ---

message Resource {
  enum Type {
    TYPE_UNKNOWN = 0;
    TYPE_SYSTEM = 1;
    TYPE_FILE = 2;
    TYPE_SHARE = 3;
    TYPE_SETTING = 4;
    TYPE_BUNDLE = 5;
    TYPE_USER = 6;
    TYPE_GROUP = 7;
  }
  Type type = 1;
  string id = 2;
}

// ---
// payloads for bundles
// ---

message Bundle {
  enum Type {
    TYPE_UNKNOWN = 0;
    TYPE_DEFAULT = 1;
    TYPE_ROLE = 2;
  }
  string id = 1;
  string name = 2;
  Type type = 3;
  string extension = 4;
  string display_name = 5;
  repeated Setting settings = 6;
  Resource resource = 7;
}

message Setting {
  string id = 1;
  string name = 2;
  string display_name = 3;
  string description = 4;
  oneof value {
    Int int_value = 5;
    String string_value = 6;
    Bool bool_value = 7;
    SingleChoiceList single_choice_value = 8;
    MultiChoiceList multi_choice_value = 9;
    Permission permission_value = 10;
  }
  Resource resource = 11;
}

message Int {
  int64 default = 1;
  int64 min = 2;
  int64 max = 3;
  int64 step = 4;
  string placeholder = 5;
}

message String {
  string default = 1;
  bool required = 2;
  int32 min_length = 3;
  int32 max_length = 4;
  string placeholder = 5;
}

message Bool {
  bool default = 1;
  string label = 2;
}

message SingleChoiceList {
  repeated ListOption options = 1;
}

message MultiChoiceList {
  repeated ListOption options = 1;
}

message ListOption {
  ListOptionValue value = 1;
  bool default = 2;
  string display_value = 3;
}

message Permission {
  enum Operation {
    OPERATION_UNKNOWN = 0;
    OPERATION_CREATE = 1;
    OPERATION_READ = 2;
    OPERATION_UPDATE = 3;
    OPERATION_DELETE = 4;
    OPERATION_WRITE = 5;// WRITE is a combination of CREATE and UPDATE
    OPERATION_READWRITE = 6;// READWRITE is a combination of READ and WRITE
  }
  Operation operation = 1;
  enum Constraint {
    CONSTRAINT_UNKNOWN = 0;
    CONSTRAINT_OWN = 1;
    CONSTRAINT_SHARED = 2;
    CONSTRAINT_ALL = 3;
  }
  Constraint constraint = 2;
}

// ---
// payloads for values
// ---

message Value {
  // id is the id of the Value. It is generated on saving it.
  string id = 1;
  string bundle_id = 2;
  // setting_id is the id of the setting from within its bundle.
  string setting_id = 3;
  string account_uuid = 4;
  Resource resource = 5;
  oneof value {
    bool bool_value = 6;
    int64 int_value = 7;
    string string_value = 8;
    ListValue list_value = 9;
  }
}

message ListValue {
  repeated ListOptionValue values = 1;
}

message ListOptionValue {
  oneof option {
    string string_value = 1;
    int64 int_value = 2;
  }
}
