syntax = "proto3";

import "lint.proto";
import "shared.proto";

package gitaly;

option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb";

service WikiService {
  rpc WikiWritePage(stream WikiWritePageRequest) returns (WikiWritePageResponse) {
    option (op_type) = {
      op: MUTATOR
    };
  }
  rpc WikiUpdatePage(stream WikiUpdatePageRequest) returns (WikiUpdatePageResponse) {
    option (op_type) = {
      op: MUTATOR
    };
  }
  // WikiFindPage returns a stream because the page's raw_data field may be arbitrarily large.
  rpc WikiFindPage(WikiFindPageRequest) returns (stream WikiFindPageResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }
  rpc WikiGetAllPages(WikiGetAllPagesRequest) returns (stream WikiGetAllPagesResponse) {
    option (op_type) = {
      op: ACCESSOR
    };

  }
  rpc WikiListPages(WikiListPagesRequest) returns (stream WikiListPagesResponse) {
    option (op_type) = {
      op: ACCESSOR
    };

  }
}

message WikiCommitDetails {
  bytes name = 1;
  bytes email = 2;
  bytes message = 3;
  int32 user_id = 4;
  bytes user_name = 5;
}

message WikiPageVersion {
  GitCommit commit = 1;
  string format = 2;
}

message WikiPage {
  // These fields are only present in the first message of a WikiPage stream
  WikiPageVersion version = 1;
  string format = 2;
  bytes title = 3;
  string url_path = 4;
  bytes path = 5;
  bytes name = 6;
  bool historical = 7;

  // This field is present in all messages of a WikiPage stream
  bytes raw_data = 8;
}

// This message is sent in a stream because the 'content' field may be large.
message WikiWritePageRequest {
  // These following fields are only present in the first message.
  Repository repository = 1 [(target_repository)=true];
  bytes name = 2;
  string format = 3;
  WikiCommitDetails commit_details = 4;
  // This field is present in all messages.
  bytes content = 5;
}

message WikiWritePageResponse {
  bytes duplicate_error = 1;
}

message WikiUpdatePageRequest {
  // There fields are only present in the first message of the stream
  Repository repository = 1 [(target_repository)=true];
  bytes page_path = 2;
  bytes title = 3;
  string format = 4;
  WikiCommitDetails commit_details = 5;

  // This field is present in all messages
  bytes content = 6;
}

message WikiUpdatePageResponse {
  bytes error = 1;
}

message WikiFindPageRequest {
  Repository repository = 1 [(target_repository)=true];
  bytes title = 2;
  bytes revision = 3;
  bytes directory = 4;
  // prevents the content from being sent over the response
  bool skip_content = 5;
}

// WikiFindPageResponse is a stream because we need multiple WikiPage
// messages to send the raw_data field.
message WikiFindPageResponse {
  WikiPage page = 1;
}

message WikiGetAllPagesRequest {
  Repository repository = 1 [(target_repository)=true];
  // Passing 0 means no limit is applied
  uint32 limit = 2;
  bool direction_desc = 3;

  enum SortBy {
    TITLE = 0;
    CREATED_AT = 1;
  }
  SortBy sort = 4;
}

// The WikiGetAllPagesResponse stream is a concatenation of WikiPage streams
message WikiGetAllPagesResponse {
  WikiPage page = 1;
  // When end_of_page is true it signals a change of page for the next Response message (if any)
  bool end_of_page = 2;
}

message WikiListPagesRequest {
  Repository repository = 1 [(target_repository)=true];
  // Passing 0 means no limit is applied
  uint32 limit = 2;
  bool direction_desc = 3;

  enum SortBy {
    TITLE = 0;
    CREATED_AT = 1;
  }
  SortBy sort = 4;

  uint32 offset = 5;
}

// The WikiListPagesResponse stream is a concatenation of WikiPage streams without content
message WikiListPagesResponse {
  WikiPage page = 1;
}
