syntax = "proto3";

package content;

import "google/protobuf/any.proto";
import "google/protobuf/empty.proto";
import "user/user.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/descriptor.proto";
import "content/blog.proto";
import "content/chatgpt/conversation.proto";
import "content/browser/history.proto";

option go_package = "./gen";

service ContentService {
  rpc Save(Contents) returns (ContentIDs);
  rpc Search(Query) returns (Results);
  rpc Relate(RelateRequest) returns (google.protobuf.Empty);
  rpc Analyze(Content) returns (Contents);
  rpc Delete(ContentIDs) returns (ContentIDs);
  rpc GetTags(TagRequest) returns (Tags);
  rpc SetTags(SetTagsRequest) returns (google.protobuf.Empty);
  rpc Publish(ContentIDs) returns (ContentIDs);
  rpc GetSources(GetSourcesRequest) returns (Sources);
  rpc Infer(InferRequest) returns (stream InferResponse);
  rpc Types(google.protobuf.Empty) returns (TypesResponse);
  rpc VoiceInput(VoiceInputRequest) returns (stream VoiceInputResponse);
}

message InferRequest {
  string prompt = 1;
}

message InferResponse {
  string text = 1;
}


message TypesResponse {
  GRPCTypeInfo content = 1;
  GRPCTypeInfo site = 2;
}

message GetSourcesRequest {
  repeated string content_types = 1;
  repeated string tags = 2;
}

message VoiceInputRequest {
  int32 capture_device = 1;
}

message VoiceInputResponse {
  Segment segment = 1;
}

message RelateRequest {
  string parent = 1;
  repeated string children = 2;
  bool connect = 3;
}

message Sources {
  repeated EnumeratedSource sources = 1;
}

message EnumeratedSource {
  Source source = 1;
  repeated DisplayContent display_content = 2;
}

message DisplayContent {
  string title = 1;
  string description = 2;
  string type = 3;
  Content content = 4;
}

message Source {
  string name = 1;
  oneof type {
    Server server = 2;
    Folder folder = 3;
  }
}

message Server {
}

message Folder {
  string path = 2;
}

message SetTagsRequest {
  string content_id = 1;
  repeated string tags = 2;
}

message TagRequest {
  string group_id = 1;
}

message Tags {
  repeated Tag tags = 1;
}

message Tag {
  string name = 1;
  repeated Tag sub_tags = 2;
}

message ContentIDs {
  repeated string content_ids = 1;
}

message Contents {
  Content content = 1;
  repeated string tags = 2;
  repeated Content related = 3;
  repeated string parents = 4;
}

message Query {
  string query = 1;
  uint32 page = 2;
  string contentID = 3;
  string groupID = 4;
  repeated string tags = 5;
  repeated string content_types = 6;
}

message Results {
  repeated StoredContent storedContent = 1;
}

message StoredContent {
  Content content = 1;
  string id = 2;
  repeated Content related = 3;
  string title = 4;
  string description = 5;
  string image = 6;
  string url = 7;
  user.User user = 9;
  repeated Tag tags = 10;
  string preview = 11;
}

message Edge {
  string from = 1;
  string to = 2;
}

extend google.protobuf.FieldOptions {
  // TODO breadchris make this a message for more robust settings?
  bool ui_hide_field = 50001;
}

// Content has data and metadata
message Content {
  repeated string tags = 1 [(ui_hide_field) = true];
  string created_at = 2;
  string uri = 3;
  string id = 4;
  oneof type {
    Data data = 6;
    Normalized normalized = 7;
    Transformed transformed = 8;
    Post post = 9;
    Site site = 10;
    chatgpt.Conversation chatgpt_conversation = 11;
    browser.History browser_history = 12;
  };
}

message Post {
  string title = 1;
  string summary = 2;
  string content = 3;
  repeated string authors = 4;
  bool draft = 6;
}

message GitRepo {
  string url = 1;
}

message Data {
  oneof type {
    Text text = 4;
    File file = 5;
    URL url = 6;
  }
}

message Normalized {
  oneof type {
    Article article = 3;
    HTML html = 4;
    Transcript transcript = 6;
    ReadMe readme = 7;
  }
}

message Transformed {
  oneof type {
    Summary summary = 1;
    Categories categories = 2;
  }
}

message Article {
  string title = 1;
  string author = 2;
  int32 length = 3;
  string excerpt = 4;
  string site_name = 5;
  string image = 6;
  string favicon = 7;
  string text = 8;
}

message HTML {
  string html = 1;
}

message ReadMe {
  string data = 1;
}

message Summary {
  string summary = 1;
}

message Categories {
  repeated string categories = 1;
}

message File {
  string file = 1;
  bytes data = 2;
  string url = 3;
}

message Text {
  string data = 1;
}

message URL {
  string url = 1;
  bool crawl = 2;
  string title = 3;
}

message Token {
  uint32 id = 1;
  uint64 start_time = 2;
  uint64 end_time = 3;
  string text = 4;
  string p = 5;
}

message Segment {
  uint32 num = 1;
  repeated Token tokens = 2;
  string text = 3;
  uint64 start_time = 4;
  uint64 end_time = 5;

}

message Transcript {
  string id = 1;
  string name = 2;
  repeated Segment segments = 3;
}

message GRPCTypeInfo {
  google.protobuf.DescriptorProto msg = 1;
  map<string, google.protobuf.DescriptorProto> desc_lookup = 3;
  map<string, google.protobuf.EnumDescriptorProto> enum_lookup = 4;
  string package_name = 6;
}

message Site {
  repeated Section sections = 1;
  HugoConfig hugo_config = 2;
}

message Section {
  // TODO breadchris tags should be a filter that can have AND, OR, regex?
  repeated string tags = 1;
  MenuItem menu = 2;
}