syntax = "proto3";

import "google/protobuf/timestamp.proto";
import "gogoproto/gogo.proto";
// import "validate/validate.proto";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
import "api/v1/attachment.proto";
import "api/v1/user.proto";

package api.v1;

option go_package = "moredoc/api/v1;v1";
option java_multiple_files = true;
option java_package = "api.v1";

message Document {
  int64 id = 1;
  string title = 2;
  string keywords = 3;
  string description = 4;
  int64 user_id = 5;
  string cover = 6;
  int32 width = 7;
  int32 height = 8;
  int32 preview = 9;
  int32 pages = 10;
  string uuid = 11;
  int32 download_count = 12;
  int32 view_count = 13;
  int32 favorite_count = 14;
  int32 comment_count = 15;
  int32 score = 16;
  int32 score_count = 17;
  int32 price = 18;
  int64 size = 19;
  int32 status = 20;
  google.protobuf.Timestamp created_at = 21 [ (gogoproto.stdtime) = true ];
  google.protobuf.Timestamp updated_at = 22 [ (gogoproto.stdtime) = true ];
  google.protobuf.Timestamp deleted_at = 23 [ (gogoproto.stdtime) = true ];
  google.protobuf.Timestamp recommend_at = 29 [ (gogoproto.stdtime) = true ];
  int64 deleted_user_id = 24;
  string username = 25;
  repeated int64 category_id = 26;
  string deleted_username = 27;
  string ext = 28;
  Attachment attachment = 30;
  User user = 31;
  bool enable_gzip = 32;
}

message DeleteDocumentRequest { repeated int64 id = 1; }
message RecoverRecycleDocumentRequest { repeated int64 id = 1; }

message GetDocumentRequest {
  int64 id = 1;
  bool with_author = 2;
}

message ListDocumentRequest {
  int64 page = 1;
  int64 size = 2;
  string wd = 3;
  repeated string field = 4;
  string order = 5;
  repeated int64 category_id = 6;
  repeated int64 user_id = 7;
  repeated int32 status = 8;
  repeated bool is_recommend = 9;
  int64 limit = 10;
}

message ListDocumentReply {
  int64 total = 1;
  repeated Document document = 2;
}

message CreateDocumentItem {
  string title = 1;
  int64 attachment_id = 2;
  int32 price = 3;
}

message CreateDocumentRequest {
  bool overwrite = 1;
  repeated int64 category_id = 2;
  repeated CreateDocumentItem document = 3;
}

message SetDocumentRecommendRequest {
  repeated int64 id = 1;
  int32 type = 2; // 0, 取消推荐，1:推荐 2:重新推荐
}

message ListDocumentForHomeRequest { int64 limit = 1; }

message ListDocumentForHomeItem {
  int64 category_id = 1;
  string category_cover = 2;
  string category_name = 3;
  repeated Document document = 4;
}

message ListDocumentForHomeResponse {
  repeated ListDocumentForHomeItem document = 1;
}

message SearchDocumentRequest {
  int32 page = 1;
  int32 size = 2;
  string wd = 3;
  repeated int64 category_id = 4; // 分类
  string sort = 5;                // 排序
  string ext = 7;                 // 类型
}

message DocumentScore {
  int64 id = 1;
  int64 document_id = 2;
  int64 user_id = 3;
  int32 score = 4;
  google.protobuf.Timestamp created_at = 5 [ (gogoproto.stdtime) = true ];
  google.protobuf.Timestamp updated_at = 6 [ (gogoproto.stdtime) = true ];
}

message SearchDocumentReply {
  int64 total = 1;
  string spend = 2; // 搜索耗时
  repeated Document document = 3;
}

message DownloadDocumentReply { string url = 1; }

service DocumentAPI {
  rpc ListDocumentForHome(ListDocumentForHomeRequest)
      returns (ListDocumentForHomeResponse) {
    option (google.api.http) = {
      get : '/api/v1/document/home',
    };
  }

  rpc SetDocumentRecommend(SetDocumentRecommendRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      put : '/api/v1/document/recommend',
      body : '*',
    };
  }

  rpc CreateDocument(CreateDocumentRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post : '/api/v1/document',
      body : '*',
    };
  }

  rpc UpdateDocument(Document) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      put : '/api/v1/document',
      body : '*',
    };
  }

  rpc DeleteDocument(DeleteDocumentRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete : '/api/v1/document',
    };
  }

  rpc GetDocument(GetDocumentRequest) returns (Document) {
    option (google.api.http) = {
      get : '/api/v1/document',
    };
  }

  rpc GetRelatedDocuments(Document) returns (ListDocumentReply) {
    option (google.api.http) = {
      get : '/api/v1/document/related',
    };
  }

  rpc DownloadDocument(Document) returns (DownloadDocumentReply) {
    option (google.api.http) = {
      get : '/api/v1/document/download',
    };
  }

  rpc ListDocument(ListDocumentRequest) returns (ListDocumentReply) {
    option (google.api.http) = {
      get : '/api/v1/document/list',
    };
  }

  rpc SearchDocument(SearchDocumentRequest) returns (SearchDocumentReply) {
    option (google.api.http) = {
      get : '/api/v1/document/search',
    };
  }

  // 设置文档评分
  rpc SetDocumentScore(DocumentScore) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post : '/api/v1/document/score',
      body : '*',
    };
  }

  // 获取当前登录用户的文档评分
  rpc GetDocumentScore(DocumentScore) returns (DocumentScore) {
    option (google.api.http) = {
      get : '/api/v1/document/score',
    };
  }
}

service RecycleAPI {
  // 文档回收站列表
  rpc ListRecycleDocument(ListDocumentRequest) returns (ListDocumentReply) {
    option (google.api.http) = {
      get : '/api/v1/document/recycle',
    };
  }

  // 恢复回收站文档，支持恢复单个文档或者是批量恢复
  rpc RecoverRecycleDocument(RecoverRecycleDocumentRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      put : '/api/v1/document/recycle',
      body : '*',
    };
  }

  // 删除回收站文档
  rpc DeleteRecycleDocument(DeleteDocumentRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete : '/api/v1/document/recycle',
    };
  }

  // 清空回收站文档
  rpc ClearRecycleDocument(google.protobuf.Empty)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete : '/api/v1/document/recycle/all',
    };
  }
}