syntax = "proto3";

package memos.api.v1;

import "google/api/annotations.proto";

option go_package = "gen/api/v1";

service MarkdownService {
  // ParseMarkdown parses the given markdown content and returns a list of nodes.
  rpc ParseMarkdown(ParseMarkdownRequest) returns (ParseMarkdownResponse) {
    option (google.api.http) = {
      post: "/api/v1/markdown:parse"
      body: "*"
    };
  }
  // RestoreMarkdownNodes restores the given nodes to markdown content.
  rpc RestoreMarkdownNodes(RestoreMarkdownNodesRequest) returns (RestoreMarkdownNodesResponse) {
    option (google.api.http) = {
      post: "/api/v1/markdown/node:restore"
      body: "*"
    };
  }
  // StringifyMarkdownNodes stringify the given nodes to plain text content.
  rpc StringifyMarkdownNodes(StringifyMarkdownNodesRequest) returns (StringifyMarkdownNodesResponse) {
    option (google.api.http) = {
      post: "/api/v1/markdown/node:stringify"
      body: "*"
    };
  }
  // GetLinkMetadata returns metadata for a given link.
  rpc GetLinkMetadata(GetLinkMetadataRequest) returns (LinkMetadata) {
    option (google.api.http) = {get: "/api/v1/markdown/link:metadata"};
  }
}

message ParseMarkdownRequest {
  string markdown = 1;
}

message ParseMarkdownResponse {
  repeated Node nodes = 1;
}

message RestoreMarkdownNodesRequest {
  repeated Node nodes = 1;
}

message RestoreMarkdownNodesResponse {
  string markdown = 1;
}

message StringifyMarkdownNodesRequest {
  repeated Node nodes = 1;
}

message StringifyMarkdownNodesResponse {
  string plain_text = 1;
}

message GetLinkMetadataRequest {
  string link = 1;
}

message LinkMetadata {
  string title = 1;
  string description = 2;
  string image = 3;
}

enum NodeType {
  NODE_UNSPECIFIED = 0;

  // Block nodes.
  LINE_BREAK = 1;
  PARAGRAPH = 2;
  CODE_BLOCK = 3;
  HEADING = 4;
  HORIZONTAL_RULE = 5;
  BLOCKQUOTE = 6;
  LIST = 7;
  ORDERED_LIST_ITEM = 8;
  UNORDERED_LIST_ITEM = 9;
  TASK_LIST_ITEM = 10;
  MATH_BLOCK = 11;
  TABLE = 12;
  EMBEDDED_CONTENT = 13;

  // Inline nodes.
  TEXT = 51;
  BOLD = 52;
  ITALIC = 53;
  BOLD_ITALIC = 54;
  CODE = 55;
  IMAGE = 56;
  LINK = 57;
  AUTO_LINK = 58;
  TAG = 59;
  STRIKETHROUGH = 60;
  ESCAPING_CHARACTER = 61;
  MATH = 62;
  HIGHLIGHT = 63;
  SUBSCRIPT = 64;
  SUPERSCRIPT = 65;
  REFERENCED_CONTENT = 66;
  SPOILER = 67;
  HTML_ELEMENT = 68;
}

message Node {
  NodeType type = 1;

  oneof node {
    // Block nodes.
    LineBreakNode line_break_node = 11;
    ParagraphNode paragraph_node = 12;
    CodeBlockNode code_block_node = 13;
    HeadingNode heading_node = 14;
    HorizontalRuleNode horizontal_rule_node = 15;
    BlockquoteNode blockquote_node = 16;
    ListNode list_node = 17;
    OrderedListItemNode ordered_list_item_node = 18;
    UnorderedListItemNode unordered_list_item_node = 19;
    TaskListItemNode task_list_item_node = 20;
    MathBlockNode math_block_node = 21;
    TableNode table_node = 22;
    EmbeddedContentNode embedded_content_node = 23;

    // Inline nodes.
    TextNode text_node = 51;
    BoldNode bold_node = 52;
    ItalicNode italic_node = 53;
    BoldItalicNode bold_italic_node = 54;
    CodeNode code_node = 55;
    ImageNode image_node = 56;
    LinkNode link_node = 57;
    AutoLinkNode auto_link_node = 58;
    TagNode tag_node = 59;
    StrikethroughNode strikethrough_node = 60;
    EscapingCharacterNode escaping_character_node = 61;
    MathNode math_node = 62;
    HighlightNode highlight_node = 63;
    SubscriptNode subscript_node = 64;
    SuperscriptNode superscript_node = 65;
    ReferencedContentNode referenced_content_node = 66;
    SpoilerNode spoiler_node = 67;
    HTMLElementNode html_element_node = 68;
  }
}

message LineBreakNode {}

message ParagraphNode {
  repeated Node children = 1;
}

message CodeBlockNode {
  string language = 1;
  string content = 2;
}

message HeadingNode {
  int32 level = 1;
  repeated Node children = 2;
}

message HorizontalRuleNode {
  string symbol = 1;
}

message BlockquoteNode {
  repeated Node children = 1;
}

message ListNode {
  enum Kind {
    KIND_UNSPECIFIED = 0;
    ORDERED = 1;
    UNORDERED = 2;
    DESCRIPTION = 3;
  }
  Kind kind = 1;
  int32 indent = 2;
  repeated Node children = 3;
}

message OrderedListItemNode {
  string number = 1;
  int32 indent = 2;
  repeated Node children = 3;
}

message UnorderedListItemNode {
  string symbol = 1;
  int32 indent = 2;
  repeated Node children = 3;
}

message TaskListItemNode {
  string symbol = 1;
  int32 indent = 2;
  bool complete = 3;
  repeated Node children = 4;
}

message MathBlockNode {
  string content = 1;
}

message TableNode {
  repeated Node header = 1;
  repeated string delimiter = 2;

  message Row {
    repeated Node cells = 1;
  }
  repeated Row rows = 3;
}

message EmbeddedContentNode {
  string resource_name = 1;
  string params = 2;
}

message TextNode {
  string content = 1;
}

message BoldNode {
  string symbol = 1;
  repeated Node children = 2;
}

message ItalicNode {
  string symbol = 1;
  string content = 2;
}

message BoldItalicNode {
  string symbol = 1;
  string content = 2;
}

message CodeNode {
  string content = 1;
}

message ImageNode {
  string alt_text = 1;
  string url = 2;
}

message LinkNode {
  string text = 1;
  string url = 2;
}

message AutoLinkNode {
  string url = 1;
  bool is_raw_text = 2;
}

message TagNode {
  string content = 1;
}

message StrikethroughNode {
  string content = 1;
}

message EscapingCharacterNode {
  string symbol = 1;
}

message MathNode {
  string content = 1;
}

message HighlightNode {
  string content = 1;
}

message SubscriptNode {
  string content = 1;
}

message SuperscriptNode {
  string content = 1;
}

message ReferencedContentNode {
  string resource_name = 1;
  string params = 2;
}

message SpoilerNode {
  string content = 1;
}

message HTMLElementNode {
  string tag_name = 1;
  map<string, string> attributes = 2;
}
