syntax = "proto3";

package ocis.services.accounts.v0;

option go_package = "github.com/jvillafanez/prototest001/gen/ocis/services/accounts/v0";

import "ocis/messages/accounts/v0/accounts.proto";
import "google/api/field_behavior.proto";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "protoc-gen-openapiv2/options/annotations.proto";

option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
  info: {
    title: "ownCloud Infinite Scale accounts";
    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/accounts/";
  };
};

// Follow recommended Methods for rpc APIs https://cloud.google.com/apis/design/resources?hl=de#methods
// https://cloud.google.com/apis/design/standard_methods?hl=de#list
// https://cloud.google.com/apis/design/naming_convention?hl=de
service AccountsService {
    // Lists accounts
    rpc ListAccounts(ListAccountsRequest) returns (ListAccountsResponse) {
        // List method maps to HTTP GET
        option (google.api.http) = {
            post: "/api/v0/accounts/accounts-list",
            body: "*"
        };
    }
    // Gets an account
    rpc GetAccount(GetAccountRequest) returns (ocis.messages.accounts.v0.Account) {
        option (google.api.http) = {
            post: "/api/v0/accounts/accounts-get",
            body: "*"
        };
    }
    // Creates an account
    rpc CreateAccount(CreateAccountRequest) returns (ocis.messages.accounts.v0.Account) {
        // Create maps to HTTP POST. URL path as the collection name.
        // HTTP request body contains the resource
        option (google.api.http) = {
            post: "/api/v0/accounts/accounts-create"
            body: "*"
        };
    }
    // Updates an account
    rpc UpdateAccount(UpdateAccountRequest) returns (ocis.messages.accounts.v0.Account) {
        // Update maps to HTTP PATCH. Resource name is mapped to a URL path.
        // Resource is contained in the HTTP request body
        option (google.api.http) = {
            post: "/api/v0/accounts/accounts-update"
            body: "*"
        };
    };
    // Deletes an account
    rpc DeleteAccount(DeleteAccountRequest) returns (google.protobuf.Empty) {
        // Delete maps to HTTP DELETE. Resource name maps to the URL path.
        // There is no request body
        option (google.api.http) = {
            post: "/api/v0/accounts/accounts-delete",
            body: "*"
        };
    }
}

service GroupsService {
    // Lists groups
    rpc ListGroups(ListGroupsRequest) returns (ListGroupsResponse) {
        // List method maps to HTTP GET
        option (google.api.http) = {
            post: "/api/v0/accounts/groups-list",
            body: "*"
        };
    }
    // Gets an groups
    rpc GetGroup(GetGroupRequest) returns (ocis.messages.accounts.v0.Group) {
        option (google.api.http) = {
            post: "/api/v0/accounts/groups-get",
            body: "*"
        };
    }
    // Creates a group
    rpc CreateGroup(CreateGroupRequest) returns (ocis.messages.accounts.v0.Group) {
        // Create maps to HTTP POST. URL path as the collection name.
        // HTTP request body contains the resource
        option (google.api.http) = {
            post: "/api/v0/accounts/groups-create"
            body: "*"
        };
    }
    // Updates a group
    rpc UpdateGroup(UpdateGroupRequest) returns (ocis.messages.accounts.v0.Group) {
        // Update maps to HTTP PATCH. Resource name is mapped to a URL path.
        // Resource is contained in the HTTP request body
        option (google.api.http) = {
            post: "/api/v0/accounts/groups-update"
            body: "*"
        };
    };
    // Deletes a group
    rpc DeleteGroup(DeleteGroupRequest) returns (google.protobuf.Empty) {
        // Delete maps to HTTP DELETE. Resource name maps to the URL path.
        // There is no request body
        option (google.api.http) = {
            post: "/api/v0/accounts/groups-delete",
            body: "*"
        };
    }

    // additional group methods: https://docs.microsoft.com/en-us/graph/api/resources/group?view=graph-rest-1.0#methods

    // references are accessed using $ref, see http://docs.oasis-open.org/odata/odata/v4.0/cs01/part2-url-conventions/odata-v4.0-cs01-part2-url-conventions.html#_Toc365046422
    // or the stack overflow question https://stackoverflow.com/questions/49362894/why-is-the-microsoft-graph-api-using-ref-in-the-uri

    // group:addmember https://docs.microsoft.com/en-us/graph/api/group-post-members?view=graph-rest-1.0&tabs=http
    rpc AddMember(AddMemberRequest) returns (ocis.messages.accounts.v0.Group) {
        //  All request parameters go into body.
        option (google.api.http) = {
            post: "/api/v0/groups/{group_id=*}/members/$ref"
            body: "*"
        };
    }
    // group:removemember https://docs.microsoft.com/en-us/graph/api/group-delete-members?view=graph-rest-1.0
    rpc RemoveMember(RemoveMemberRequest) returns (ocis.messages.accounts.v0.Group) {
        //  All request parameters go into body.
        option (google.api.http) = {
            // URLs are broken
            post: "/api/v0/groups/{group_id=*}/members/{account_id}/$ref"
            body: "*"
        };
    }
    // group:listmembers https://docs.microsoft.com/en-us/graph/api/group-list-members?view=graph-rest-1.0
    rpc ListMembers(ListMembersRequest) returns (ListMembersResponse) {
        //  All request parameters go into body.
        option (google.api.http) = {
            // URLs are broken
            post: "/api/v0/groups/{id=*}/members/$ref"
            body: "*"
        };
    }

}

service IndexService {
    rpc RebuildIndex(RebuildIndexRequest) returns (RebuildIndexResponse) {
        //  All request parameters go into body.
        option (google.api.http) = {
            // URLs are broken
            post: "/api/v0/index/rebuild"
            body: "*"
        };
    }
}

message RebuildIndexRequest {
}

message RebuildIndexResponse {
}

message ListAccountsRequest {
    // Optional. The maximum number of accounts to return in the response
    int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. A pagination token returned from a previous call to `Get`
    // that indicates from where search should continue
    string page_token = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Used to specify a subset of fields that should be
    // returned by a get operation or modified by an update operation.
    google.protobuf.FieldMask field_mask = 3;

    // Optional. Search criteria used to select the accounts to return.
    // If no search criteria is specified then all accounts will be
    // returned
    //
    // TODO update query language
    // Query expressions can be used to restrict results based upon
    // the account properties where the operators `=`, `NOT`, `AND` and `OR`
    // can be used along with the suffix wildcard symbol `*`.
    //
    // The string properties in a query expression should use escaped quotes
    // for values that include whitespace to prevent unexpected behavior.
    //
    // Some example queries are:
    //
    // * Query `display_name=Th*` returns accounts whose display_name
    // starts with "Th"
    // * Query `email=foo@example.com` returns accounts with
    // `email` set to `foo@example.com`
    // * Query `display_name=\\"Test String\\"` returns accounts with
    // display names that include both "Test" and "String"
    string query = 4 [(google.api.field_behavior) = OPTIONAL];
}

message ListAccountsResponse {
    // The field name should match the noun "accounts" in the method name.  There
    // will be a maximum number of items returned based on the page_size field
    // in the request
    repeated ocis.messages.accounts.v0.Account accounts = 1;

    // Token to retrieve the next page of results, or empty if there are no
    // more results in the list
    string next_page_token = 2;
}

message GetAccountRequest {
    string id = 1;
}

message CreateAccountRequest {
    // The account resource to create
    ocis.messages.accounts.v0.Account account = 1;
}

message UpdateAccountRequest {
    // The account resource which replaces the resource on the server
    ocis.messages.accounts.v0.Account account = 1;

    // The update mask applies to the resource. For the `FieldMask` definition,
    // see https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask
    google.protobuf.FieldMask update_mask = 2;
  }

message DeleteAccountRequest {
    string id = 1;
}

message ListGroupsRequest {
    // Optional. The maximum number of groups to return in the response
    int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. A pagination token returned from a previous call to `Get`
    // that indicates from where search should continue
    string page_token = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Used to specify a subset of fields that should be
    // returned by a get operation or modified by an update operation.
    google.protobuf.FieldMask field_mask = 3;

    // Optional. Search criteria used to select the groups to return.
    // If no search criteria is specified then all groups will be
    // returned
    //
    // TODO update query language
    // Query expressions can be used to restrict results based upon
    // the account properties where the operators `=`, `NOT`, `AND` and `OR`
    // can be used along with the suffix wildcard symbol `*`.
    //
    // The string properties in a query expression should use escaped quotes
    // for values that include whitespace to prevent unexpected behavior.
    //
    // Some example queries are:
    //
    // * Query `display_name=Th*` returns accounts whose display_name
    // starts with "Th"
    // * Query `display_name=\\"Test String\\"` returns groups with
    // display names that include both "Test" and "String"
    string query = 4 [(google.api.field_behavior) = OPTIONAL];
}

message ListGroupsResponse {
    // The field name should match the noun "group" in the method name.  There
    // will be a maximum number of items returned based on the page_size field
    // in the request
    repeated ocis.messages.accounts.v0.Group groups = 1;

    // Token to retrieve the next page of results, or empty if there are no
    // more results in the list
    string next_page_token = 2;
}

message GetGroupRequest {
    string id = 1;
}

message CreateGroupRequest {
    // The account resource to create
    ocis.messages.accounts.v0.Group group = 1;
}

message UpdateGroupRequest {
    // The group resource which replaces the resource on the server
    ocis.messages.accounts.v0.Group group = 1;

    // The update mask applies to the resource. For the `FieldMask` definition,
    // see https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask
    google.protobuf.FieldMask update_mask = 2;
  }

message DeleteGroupRequest {
    string id = 1;
}

message AddMemberRequest {
    // The id of the group to add a member to
    string group_id = 1;
    // The account id to add
    string account_id = 2;
}

message RemoveMemberRequest {
    // The id of the group to remove a member from
    string group_id = 1;
    // The account id to remove
    string account_id = 2;
}

message ListMembersRequest {
    int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. A pagination token returned from a previous call to `Get`
    // that indicates from where search should continue
    string page_token = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Used to specify a subset of fields that should be
    // returned by a get operation or modified by an update operation.
    google.protobuf.FieldMask field_mask = 3;

    // Optional. Search criteria used to select the groups to return.
    // If no search criteria is specified then all groups will be
    // returned
    //
    // TODO update query language
    // Query expressions can be used to restrict results based upon
    // the account properties where the operators `=`, `NOT`, `AND` and `OR`
    // can be used along with the suffix wildcard symbol `*`.
    //
    // The string properties in a query expression should use escaped quotes
    // for values that include whitespace to prevent unexpected behavior.
    //
    // Some example queries are:
    //
    // * Query `display_name=Th*` returns accounts whose display_name
    // starts with "Th"
    // * Query `display_name=\\"Test String\\"` returns groups with
    // display names that include both "Test" and "String"
    string query = 4 [(google.api.field_behavior) = OPTIONAL];

    // The id of the group to list members from
    string id = 5;
}

message ListMembersResponse {
    // The field name should match the noun "members" in the method name.  There
    // will be a maximum number of items returned based on the page_size field
    // in the request
    repeated ocis.messages.accounts.v0.Account members = 1;

    // Token to retrieve the next page of results, or empty if there are no
    // more results in the list
    string next_page_token = 2;
}
