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/permission.proto";

package api.v1;

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

message User {
  google.protobuf.Timestamp login_at = 19 [ (gogoproto.stdtime) = true ];
  google.protobuf.Timestamp created_at = 20 [ (gogoproto.stdtime) = true ];
  google.protobuf.Timestamp updated_at = 21 [ (gogoproto.stdtime) = true ];
  int64 id = 1;
  string username = 2;
  string mobile = 3;
  string email = 4;
  string address = 5;
  string signature = 6;
  string last_login_ip = 7;
  string register_ip = 8;
  int32 doc_count = 9;
  int32 follow_count = 10;
  int32 fans_count = 11;
  int32 favorite_count = 12;
  int32 comment_count = 13;
  int32 status = 14;
  string avatar = 15;
  string identity = 16;
  string realname = 17;
  repeated int64 group_id = 18;
  int32 credit_count = 22;
}

message RegisterAndLoginRequest {
  string username = 1 [ (gogoproto.moretags) = "validate:\"min=3,max=32\"" ];
  string password = 2 [ (gogoproto.moretags) = "validate:\"min=6\"" ];
  string captcha = 3;
  string captcha_id = 4;
  string email = 5;
}

message GetUserCaptchaRequest {
  string type =
      1; // 验证码类型：register、login、comment、find_password、upload
}

message LoginReply {
  string token = 1;
  User user = 2;
}

message DeleteUserRequest { repeated int64 id = 1; }

message GetUserRequest { int64 id = 1; }

message FindPasswordRequest {
  string email = 1;
  string token = 2;
  string password = 3 [ (gogoproto.moretags) = "validate:\"min=6\"" ];
  string captcha = 4;
  string captcha_id = 5;
}

message ListUserRequest {
  int64 page = 1;
  int64 size = 2;
  string wd = 3;
  string sort = 4;
  repeated int64 id = 5;
  repeated int64 group_id = 6;
  repeated int32 status = 7;
  int64 limit = 8;
}

message ListUserReply {
  int64 total = 1;
  repeated User user = 2;
}

message GetUserCaptchaReply {
  bool enable = 1;
  string id = 2;
  string captcha = 3;
  string type = 4;
}

// 修改用户密码
message UpdateUserPasswordRequest {
  int64 id = 1;
  string old_password = 2;
  string new_password = 3 [ (gogoproto.moretags) = "validate:\"min=6\"" ];
}

message GetUserPermissionsReply { repeated Permission permission = 1; }

message SetUserRequest {
  int64 id = 1;
  string username = 2 [ (gogoproto.moretags) = "validate:\"min=3,max=32\"" ];
  string password = 3 [ (gogoproto.moretags) = "validate:\"min=6\"" ];
  repeated int64 group_id = 4;
}

message Dynamic {
  int64 id = 1;
  int64 user_id = 2;
  string content = 3;
  int32 type = 4; // 类型
  string username = 7;
  google.protobuf.Timestamp created_at = 5 [ (gogoproto.stdtime) = true ];
  google.protobuf.Timestamp updated_at = 6 [ (gogoproto.stdtime) = true ];
}

message ListUserDynamicRequest {
  int64 page = 1;
  int64 size = 2;
  int64 id = 3;
}

message ListUserDynamicReply {
  int64 total = 1;
  repeated Dynamic dynamic = 2;
}

message Sign {
  int64 id = 1;
  int64 user_id = 2;
  int32 sign_at = 3;
  string ip = 4;
  google.protobuf.Timestamp created_at = 5 [ (gogoproto.stdtime) = true ];
  int32 award = 6; // 签到积分奖励
}

service UserAPI {
  // 用户注册
  rpc Register(RegisterAndLoginRequest) returns (LoginReply) {
    option (google.api.http) = {
      post : '/api/v1/user/register',
      body : '*',
    };
  }

  // 用户登录
  rpc Login(RegisterAndLoginRequest) returns (LoginReply) {
    option (google.api.http) = {
      post : '/api/v1/user/login',
      body : '*',
    };
  }

  // 退出登录
  rpc Logout(google.protobuf.Empty) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete : '/api/v1/user/logout',
    };
  }

  // 查询用户信息。如果传递了Id参数，则表示查询用户的公开信息，否则查询当前用户的私有信息
  rpc GetUser(GetUserRequest) returns (User) {
    option (google.api.http) = {
      get : '/api/v1/user',
    };
  }

  // 更新用户密码。如果不传用户ID，则表示更新当前用户的密码；
  // 如果穿了用户ID，则表示更新指定用户的密码，这时需要验证当前用户的权限
  rpc UpdateUserPassword(UpdateUserPasswordRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      put : '/api/v1/user/password',
      body : '*',
    };
  }

  // 更新用户密码。如果不传用户ID，则表示更新当前用户的密码；
  // 如果穿了用户ID，则表示更新指定用户的密码，这时需要验证当前用户的权限
  rpc UpdateUserProfile(User) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      put : '/api/v1/user/profile',
      body : '*',
    };
  }

  // 删除用户。需要验证用户权限
  rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete : '/api/v1/user',
    };
  }

  // 新增用户
  rpc AddUser(SetUserRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post : '/api/v1/user',
      body : '*',
    };
  }

  // 设置用户
  rpc SetUser(SetUserRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      put : '/api/v1/user',
      body : '*',
    };
  }

  // 查询用户列表。对于非管理员，返回相应用户的公开信息；
  // 对于管理员，返回相应用户的绝大部分信息
  rpc ListUser(ListUserRequest) returns (ListUserReply) {
    option (google.api.http) = {
      get : '/api/v1/user/list',
    };
  }

  // GetUserCaptcha 获取用户验证码
  rpc GetUserCaptcha(GetUserCaptchaRequest) returns (GetUserCaptchaReply) {
    option (google.api.http) = {
      get : '/api/v1/user/captcha',
    };
  }

  // GetUserCaptcha 获取用户验证码
  rpc GetUserPermissions(google.protobuf.Empty)
      returns (GetUserPermissionsReply) {
    option (google.api.http) = {
      get : '/api/v1/user/permission',
    };
  }

  // 用户是否可以上传文档
  rpc CanIUploadDocument(google.protobuf.Empty)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      get : '/api/v1/user/caniuploaddocument',
    };
  }

  // 获取用户动态，包括获取关注的用户的动态
  rpc ListUserDynamic(ListUserDynamicRequest) returns (ListUserDynamicReply) {
    option (google.api.http) = {
      get : '/api/v1/user/dynamic',
    };
  }

  // 每日签到
  rpc SignToday(google.protobuf.Empty) returns (Sign) {
    option (google.api.http) = {
      put : '/api/v1/user/sign',
    };
  }

  // 获取今日已签到记录
  rpc GetSignedToday(google.protobuf.Empty) returns (Sign) {
    option (google.api.http) = {
      get : '/api/v1/user/sign',
    };
  }

  rpc FindPasswordStepOne(FindPasswordRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post : '/api/v1/user/findpassword/stepone',
      body : '*',
    };
  }

  rpc FindPasswordStepTwo(FindPasswordRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      put : '/api/v1/user/findpassword/steptwo',
      body : '*',
    };
  }
}