syntax = "proto3";

package memos.api.v1;

import "api/v1/common.proto";
import "api/v1/markdown_service.proto";
import "api/v1/memo_relation_service.proto";
import "api/v1/reaction_service.proto";
import "api/v1/resource_service.proto";
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option go_package = "gen/api/v1";

service MemoService {
  // CreateMemo creates a memo.
  rpc CreateMemo(CreateMemoRequest) returns (Memo) {
    option (google.api.http) = {
      post: "/api/v1/memos"
      body: "*"
    };
  }
  // ListMemos lists memos with pagination and filter.
  rpc ListMemos(ListMemosRequest) returns (ListMemosResponse) {
    option (google.api.http) = {get: "/api/v1/memos"};
  }
  // GetMemo gets a memo.
  rpc GetMemo(GetMemoRequest) returns (Memo) {
    option (google.api.http) = {get: "/api/v1/{name=memos/*}"};
    option (google.api.method_signature) = "name";
  }
  // GetMemoByUid gets a memo by uid
  rpc GetMemoByUid(GetMemoByUidRequest) returns (Memo) {
    option (google.api.http) = {get: "/api/v1/memos:by-uid/{uid}"};
    option (google.api.method_signature) = "uid";
  }
  // UpdateMemo updates a memo.
  rpc UpdateMemo(UpdateMemoRequest) returns (Memo) {
    option (google.api.http) = {
      patch: "/api/v1/{memo.name=memos/*}"
      body: "memo"
    };
    option (google.api.method_signature) = "memo,update_mask";
  }
  // DeleteMemo deletes a memo.
  rpc DeleteMemo(DeleteMemoRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {delete: "/api/v1/{name=memos/*}"};
    option (google.api.method_signature) = "name";
  }
  // RebuildMemoProperty rebuilds a memo property.
  rpc RebuildMemoProperty(RebuildMemoPropertyRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/api/v1/{name=memos/*}/properties:rebuild"
      body: "*"
    };
  }
  // RenameMemoTag renames a tag for a memo.
  rpc RenameMemoTag(RenameMemoTagRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      patch: "/api/v1/{parent=memos/*}/tags:rename"
      body: "*"
    };
  }
  // DeleteMemoTag deletes a tag for a memo.
  rpc DeleteMemoTag(DeleteMemoTagRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {delete: "/api/v1/{parent=memos/*}/tags/{tag}"};
  }
  // SetMemoResources sets resources for a memo.
  rpc SetMemoResources(SetMemoResourcesRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      patch: "/api/v1/{name=memos/*}/resources"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }
  // ListMemoResources lists resources for a memo.
  rpc ListMemoResources(ListMemoResourcesRequest) returns (ListMemoResourcesResponse) {
    option (google.api.http) = {get: "/api/v1/{name=memos/*}/resources"};
    option (google.api.method_signature) = "name";
  }
  // SetMemoRelations sets relations for a memo.
  rpc SetMemoRelations(SetMemoRelationsRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      patch: "/api/v1/{name=memos/*}/relations"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }
  // ListMemoRelations lists relations for a memo.
  rpc ListMemoRelations(ListMemoRelationsRequest) returns (ListMemoRelationsResponse) {
    option (google.api.http) = {get: "/api/v1/{name=memos/*}/relations"};
    option (google.api.method_signature) = "name";
  }
  // CreateMemoComment creates a comment for a memo.
  rpc CreateMemoComment(CreateMemoCommentRequest) returns (Memo) {
    option (google.api.http) = {
      post: "/api/v1/{name=memos/*}/comments"
      body: "comment"
    };
    option (google.api.method_signature) = "name";
  }
  // ListMemoComments lists comments for a memo.
  rpc ListMemoComments(ListMemoCommentsRequest) returns (ListMemoCommentsResponse) {
    option (google.api.http) = {get: "/api/v1/{name=memos/*}/comments"};
    option (google.api.method_signature) = "name";
  }
  // ListMemoReactions lists reactions for a memo.
  rpc ListMemoReactions(ListMemoReactionsRequest) returns (ListMemoReactionsResponse) {
    option (google.api.http) = {get: "/api/v1/{name=memos/*}/reactions"};
    option (google.api.method_signature) = "name";
  }
  // UpsertMemoReaction upserts a reaction for a memo.
  rpc UpsertMemoReaction(UpsertMemoReactionRequest) returns (Reaction) {
    option (google.api.http) = {
      post: "/api/v1/{name=memos/*}/reactions"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }
  // DeleteMemoReaction deletes a reaction for a memo.
  rpc DeleteMemoReaction(DeleteMemoReactionRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {delete: "/api/v1/reactions/{reaction_id}"};
    option (google.api.method_signature) = "reaction_id";
  }
}

enum Visibility {
  VISIBILITY_UNSPECIFIED = 0;
  PRIVATE = 1;
  PROTECTED = 2;
  PUBLIC = 3;
}

message Memo {
  // The name of the memo.
  // Format: memos/{id}
  // id is the system generated id.
  string name = 1;

  // The user defined id of the memo.
  string uid = 2;

  RowStatus row_status = 3;

  // The name of the creator.
  // Format: users/{id}
  string creator = 4;

  google.protobuf.Timestamp create_time = 5;

  google.protobuf.Timestamp update_time = 6;

  google.protobuf.Timestamp display_time = 7;

  string content = 8;

  repeated Node nodes = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  Visibility visibility = 10;

  repeated string tags = 11;

  bool pinned = 12;

  repeated Resource resources = 14;

  repeated MemoRelation relations = 15;

  repeated Reaction reactions = 16 [(google.api.field_behavior) = OUTPUT_ONLY];

  MemoProperty property = 17 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The name of the parent memo.
  // Format: memos/{id}
  optional string parent = 18 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The snippet of the memo content. Plain text only.
  string snippet = 19;

  // The location of the memo.
  optional Location location = 20;
}

message MemoProperty {
  repeated string tags = 1;
  bool has_link = 2;
  bool has_task_list = 3;
  bool has_code = 4;
  bool has_incomplete_tasks = 5;
}

message Location {
  string placeholder = 1;
  double latitude = 2;
  double longitude = 3;
}

message CreateMemoRequest {
  string content = 1;

  Visibility visibility = 2;

  repeated Resource resources = 3;

  repeated MemoRelation relations = 4;

  optional Location location = 5;
}

enum MemoView {
  MEMO_VIEW_UNSPECIFIED = 0;

  // The full view of the memo. Includes all fields.
  MEMO_VIEW_FULL = 1;

  // The metadata only view of the memo. Excludes the content/snippet fields.
  MEMO_VIEW_METADATA_ONLY = 2;
}

message ListMemosRequest {
  // The maximum number of memos to return.
  int32 page_size = 1;

  // A page token, received from a previous `ListMemos` call.
  // Provide this to retrieve the subsequent page.
  string page_token = 2;

  // Filter is used to filter memos returned in the list.
  // Format: "creator == 'users/{uid}' && visibilities == ['PUBLIC', 'PROTECTED']"
  string filter = 3;

  // The view of the memo.
  MemoView view = 4;
}

message ListMemosResponse {
  repeated Memo memos = 1;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

message GetMemoRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;
}

message GetMemoByUidRequest {
  // The uid of the memo.
  string uid = 1;
}

message UpdateMemoRequest {
  Memo memo = 1;

  google.protobuf.FieldMask update_mask = 2;
}

message DeleteMemoRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;
}

message RebuildMemoPropertyRequest {
  // The name of the memo.
  // Format: memos/{id}. Use "memos/-" to rebuild all memos.
  string name = 1;
}

message RenameMemoTagRequest {
  // The parent, who owns the tags.
  // Format: memos/{id}. Use "memos/-" to rename all tags.
  string parent = 1;
  string old_tag = 2;
  string new_tag = 3;
}

message DeleteMemoTagRequest {
  // The parent, who owns the tags.
  // Format: memos/{id}. Use "memos/-" to delete all tags.
  string parent = 1;
  string tag = 2;
  bool delete_related_memos = 3;
}

message SetMemoResourcesRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;

  repeated Resource resources = 2;
}

message ListMemoResourcesRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;
}

message ListMemoResourcesResponse {
  repeated Resource resources = 1;
}

message SetMemoRelationsRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;

  repeated MemoRelation relations = 2;
}

message ListMemoRelationsRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;
}

message ListMemoRelationsResponse {
  repeated MemoRelation relations = 1;
}

message CreateMemoCommentRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;

  CreateMemoRequest comment = 2;
}

message ListMemoCommentsRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;
}

message ListMemoCommentsResponse {
  repeated Memo memos = 1;
}

message ListMemoReactionsRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;
}

message ListMemoReactionsResponse {
  repeated Reaction reactions = 1;
}

message UpsertMemoReactionRequest {
  // The name of the memo.
  // Format: memos/{id}
  string name = 1;

  Reaction reaction = 2;
}

message DeleteMemoReactionRequest {
  int32 reaction_id = 1;
}
