syntax = "proto3";

package memos.api.v2;

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

option go_package = "gen/api/v2";

service MemoService {
  // CreateMemo creates a memo.
  rpc CreateMemo(CreateMemoRequest) returns (CreateMemoResponse) {
    option (google.api.http) = {
      post: "/api/v2/memos"
      body: "*"
    };
  }
  // ListMemos lists memos with pagination and filter.
  rpc ListMemos(ListMemosRequest) returns (ListMemosResponse) {
    option (google.api.http) = {get: "/api/v2/memos"};
  }
  // GetMemo gets a memo by id.
  rpc GetMemo(GetMemoRequest) returns (GetMemoResponse) {
    option (google.api.http) = {get: "/api/v2/memos/{id}"};
    option (google.api.method_signature) = "id";
  }
  // UpdateMemo updates a memo.
  rpc UpdateMemo(UpdateMemoRequest) returns (UpdateMemoResponse) {
    option (google.api.http) = {
      patch: "/api/v2/memos/{id}"
      body: "*"
    };
    option (google.api.method_signature) = "id, update_mask";
  }
  // DeleteMemo deletes a memo by id.
  rpc DeleteMemo(DeleteMemoRequest) returns (DeleteMemoResponse) {
    option (google.api.http) = {delete: "/api/v2/memos/{id}"};
    option (google.api.method_signature) = "id";
  }
  // SetMemoResources sets resources for a memo.
  rpc SetMemoResources(SetMemoResourcesRequest) returns (SetMemoResourcesResponse) {
    option (google.api.http) = {
      post: "/api/v2/memos/{id}/resources"
      body: "*"
    };
    option (google.api.method_signature) = "id";
  }
  // ListMemoResources lists resources for a memo.
  rpc ListMemoResources(ListMemoResourcesRequest) returns (ListMemoResourcesResponse) {
    option (google.api.http) = {get: "/api/v2/memos/{id}/resources"};
    option (google.api.method_signature) = "id";
  }
  // SetMemoRelations sets relations for a memo.
  rpc SetMemoRelations(SetMemoRelationsRequest) returns (SetMemoRelationsResponse) {
    option (google.api.http) = {
      post: "/api/v2/memos/{id}/relations"
      body: "*"
    };
    option (google.api.method_signature) = "id";
  }
  // ListMemoRelations lists relations for a memo.
  rpc ListMemoRelations(ListMemoRelationsRequest) returns (ListMemoRelationsResponse) {
    option (google.api.http) = {get: "/api/v2/memos/{id}/relations"};
    option (google.api.method_signature) = "id";
  }
  // CreateMemoComment creates a comment for a memo.
  rpc CreateMemoComment(CreateMemoCommentRequest) returns (CreateMemoCommentResponse) {
    option (google.api.http) = {post: "/api/v2/memos/{id}/comments"};
    option (google.api.method_signature) = "id";
  }
  // ListMemoComments lists comments for a memo.
  rpc ListMemoComments(ListMemoCommentsRequest) returns (ListMemoCommentsResponse) {
    option (google.api.http) = {get: "/api/v2/memos/{id}/comments"};
    option (google.api.method_signature) = "id";
  }
  // GetUserMemosStats gets stats of memos for a user.
  rpc GetUserMemosStats(GetUserMemosStatsRequest) returns (GetUserMemosStatsResponse) {
    option (google.api.http) = {get: "/api/v2/memos/stats"};
    option (google.api.method_signature) = "username";
  }
}

enum Visibility {
  VISIBILITY_UNSPECIFIED = 0;

  PRIVATE = 1;

  PROTECTED = 2;

  PUBLIC = 3;
}

message Memo {
  int32 id = 1;

  RowStatus row_status = 2;

  // The name of the creator.
  // Format: users/{username}
  string creator = 3;

  int32 creator_id = 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;

  Visibility visibility = 10;

  bool pinned = 11;

  optional int32 parent_id = 12;

  repeated Resource resources = 13 [(google.api.field_behavior) = OUTPUT_ONLY];

  repeated MemoRelation relations = 14 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message CreateMemoRequest {
  string content = 1;

  Visibility visibility = 2;
}

message CreateMemoResponse {
  Memo memo = 1;
}

message ListMemosRequest {
  // offset is the offset of the first memo to return.
  int32 offset = 1;

  // limit is the maximum number of memos to return.
  int32 limit = 2;

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

message ListMemosResponse {
  repeated Memo memos = 1;
}

message GetMemoRequest {
  int32 id = 1;
}

message GetMemoResponse {
  Memo memo = 1;
}

message UpdateMemoRequest {
  int32 id = 1;

  Memo memo = 2;

  google.protobuf.FieldMask update_mask = 3;
}

message UpdateMemoResponse {
  Memo memo = 1;
}

message DeleteMemoRequest {
  int32 id = 1;
}

message DeleteMemoResponse {}

message SetMemoResourcesRequest {
  int32 id = 1;

  repeated Resource resources = 2;
}

message SetMemoResourcesResponse {}

message ListMemoResourcesRequest {
  int32 id = 1;
}

message ListMemoResourcesResponse {
  repeated Resource resources = 1;
}

message SetMemoRelationsRequest {
  int32 id = 1;

  repeated MemoRelation relations = 2;
}

message SetMemoRelationsResponse {}

message ListMemoRelationsRequest {
  int32 id = 1;
}

message ListMemoRelationsResponse {
  repeated MemoRelation relations = 1;
}

message CreateMemoCommentRequest {
  // id is the memo id to create comment for.
  int32 id = 1;

  CreateMemoRequest create = 2;
}

message CreateMemoCommentResponse {
  Memo memo = 1;
}

message ListMemoCommentsRequest {
  int32 id = 1;
}

message ListMemoCommentsResponse {
  repeated Memo memos = 1;
}

message GetUserMemosStatsRequest {
  // name is the name of the user to get stats for.
  // Format: users/{username}
  string name = 1;
}

message GetUserMemosStatsResponse {
  // memo_creation_stats is the stats of memo creation.
  // key is the year-month-day string. e.g. "2020-01-01". value is the count of memos created.
  map<string, int32> memo_creation_stats = 1;
}
