syntax = "proto3";

package mubit.v1;

// Mubit CoreService gRPC service definition
service CoreService {
  // Create User (Admin only)
  rpc CreateUser(CreateUserRequest) returns (CreateUserResponse);

  // Rotate a user's API key (Admin only)
  rpc RotateUserApiKey(RotateUserApiKeyRequest) returns (RotateUserApiKeyResponse);

  // Revoke a user's API key (Admin only)
  rpc RevokeUserApiKey(RevokeUserApiKeyRequest) returns (RevokeUserApiKeyResponse);

  // List users (Admin only)
  rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);

  // Get a user (Admin or self)
  rpc GetUser(GetUserRequest) returns (GetUserResponse);

  // Delete User (Admin only)
  rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse);

  // Health check
  rpc Health(HealthRequest) returns (HealthResponse);
  
  // Insert a document
  rpc Insert(InsertRequest) returns (InsertResponse);
  
  // Get a document
  rpc GetNode(GetNodeRequest) returns (GetNodeResponse);
  
  // Delete a document
  rpc DeleteNode(DeleteNodeRequest) returns (DeleteNodeResponse);
  
  // Delete all documents in a run
  rpc DeleteRun(DeleteRunRequest) returns (DeleteRunResponse);
  
  // Search for similar documents
  rpc Search(SearchRequest) returns (SearchResponse);
  
  // Batch insert (streaming)
  rpc BatchInsert(stream InsertRequest) returns (BatchInsertResponse);
  
  // Streaming search results
  rpc StreamSearch(SearchRequest) returns (stream SearchResult);

  // ACL Operations
  rpc GrantPermission(GrantPermissionRequest) returns (GrantPermissionResponse);
  rpc RevokePermission(RevokePermissionRequest) returns (RevokePermissionResponse);
  
  // PubSub
  rpc Subscribe(CoreSubscribeRequest) returns (stream PubSubEvent);

  // SDM Write
  rpc WriteMemory(WriteMemoryRequest) returns (WriteMemoryResponse);

  // SDM Read
  rpc ReadMemory(ReadMemoryRequest) returns (ReadMemoryResponse);

  // Agent Memory (Scratchpad)
  rpc AddMemory (AddMemoryRequest) returns (AddMemoryResponse);
  rpc GetMemory (GetMemoryRequest) returns (GetMemoryResponse);
  rpc ClearMemory (ClearMemoryRequest) returns (ClearMemoryResponse);
  rpc WatchMemory (WatchMemoryRequest) returns (stream MemoryEvent);

  // Cortex Session Operations
  rpc CreateSession (CreateSessionRequest) returns (CreateSessionResponse);
  rpc SnapshotSession (SnapshotSessionRequest) returns (SnapshotSessionResponse);
  rpc LoadSession (LoadSessionRequest) returns (LoadSessionResponse);
  rpc CommitSession (CommitSessionRequest) returns (CommitSessionResponse);
  rpc DropSession (DropSessionRequest) returns (DropSessionResponse);
}

message CreateUserRequest {
  string username = 1;
  string role = 2; // "admin" or "user"
}

message CreateUserResponse {
  uint64 user_id = 1;
  string api_key = 2; // Returned once at creation time
  string message = 3;
}

message RotateUserApiKeyRequest {
  string username = 1;
}

message RotateUserApiKeyResponse {
  bool success = 1;
  string api_key = 2; // Returned once at rotation time
  string message = 3;
}

message RevokeUserApiKeyRequest {
  string username = 1;
}

message RevokeUserApiKeyResponse {
  bool success = 1;
  string message = 2;
}

message ListUsersRequest {}

message AuthUser {
  string username = 1;
  uint64 user_id = 2;
  string role = 3;
  string instance_id = 4;
  bool api_key_active = 5;
}

message ListUsersResponse {
  repeated AuthUser users = 1;
}

message GetUserRequest {
  string username = 1;
}

message GetUserResponse {
  AuthUser user = 1;
}

message DeleteUserRequest {
  string username = 1;
}

message DeleteUserResponse {
  bool success = 1;
  string message = 2;
}

// Health check
message HealthRequest {}

message HealthResponse {
  string status = 1;
  string version = 2;
}

// Node
message Node {
  uint64 id = 1;
  // Vector is internal (HDC), typically not returned to client or returned as bytes if needed
  // repeated float vector = 2; // Deprecated
  bytes metadata = 3;
  optional string run_id = 4;
}

// Insert operations
message InsertRequest {
  uint64 id = 1;
  string text = 2; // Raw text input for HDC encoding
  bytes metadata = 3;  // JSON-encoded metadata
  uint64 user_id = 4;
  optional string session_id = 5;
  repeated float embedding = 6; // Pre-computed embedding (optional)
  optional string run_id = 7;
}

message InsertResponse {
  bool success = 1;
  uint64 node_id = 2;
  string message = 3;
}

message BatchInsertResponse {
  uint32 count = 1;
  repeated uint64 node_ids = 2;
}

// Get/Delete Node
message GetNodeRequest {
  uint64 node_id = 1;
}

message GetNodeResponse {
  Node node = 1;
}

message DeleteNodeRequest {
  uint64 node_id = 1;
  optional string session_id = 2;
}

message DeleteNodeResponse {
  bool success = 1;
  string message = 2;
}

message DeleteRunRequest {
  string run_id = 1;
  uint64 user_id = 2;
}

message DeleteRunResponse {
  bool success = 1;
  string message = 2;
  uint64 count = 3;
}

// Search operations
message SearchRequest {
  string query_text = 1; // Raw text query for HDC encoding
  uint64 user_id = 2;
  uint32 k = 3;
  optional string session_id = 4;
  string filter = 5; // JSON-encoded metadata filter
  repeated float query_embedding = 6; // Pre-computed embedding (optional)
  optional string run_id = 7;
}

message SearchResponse {
  repeated SearchResult results = 1;
}

message SearchResult {
  uint64 id = 1;
  float similarity = 2;
  bytes metadata = 3;  // JSON-encoded metadata
}

// ACL Operations
message Permissions {
  bool read = 1;
  bool write = 2;
  bool delete = 3;
}

message GrantPermissionRequest {
  uint64 node_id = 1;
  uint64 target_user_id = 2;
  Permissions permissions = 3;
}

message GrantPermissionResponse {
  bool success = 1;
  string message = 2;
}

message RevokePermissionRequest {
  uint64 node_id = 1;
  uint64 target_user_id = 2;
}

message RevokePermissionResponse {
  bool success = 1;
  string message = 2;
}

// PubSub
message CoreSubscribeRequest {
  string filter_type = 1; // "all", "node", "semantic"
  optional uint64 node_id = 2;
  repeated float vector = 3; // Deprecated
  optional float threshold = 4;
  string query_text = 5; // Text to encode for semantic subscription
}

message PubSubEvent {
  string type = 1; // "inserted", "updated", "deleted"
  Node node = 2; // For inserted/updated
  uint64 node_id = 3; // For deleted
}

// SDM operations
message BitVector {
  repeated uint64 chunks = 1; // 16 chunks of 64 bits = 1024 bits
}

message WriteMemoryRequest {
  BitVector address = 1;
  BitVector data = 2;
  uint64 user_id = 3;
}

message WriteMemoryResponse {
  bool success = 1;
  string message = 2;
}

message ReadMemoryRequest {
  BitVector address = 1;
  uint64 user_id = 2;
}

message ReadMemoryResponse {
  BitVector data = 1;
}

// Agent Memory Messages

message MemoryEntry {
  string id = 1;
  string session_id = 2;
  string agent_id = 3;
  string content = 4;
  int64 timestamp = 5;
  map<string, string> metadata = 6;
  optional int64 expires_at = 7;
}

message AddMemoryRequest {
  string session_id = 1;
  string agent_id = 2;
  string content = 3;
  map<string, string> metadata = 4;
  optional int64 ttl_seconds = 5;
}

message AddMemoryResponse {
  bool success = 1;
  string message = 2;
  MemoryEntry entry = 3;
}

message GetMemoryRequest {
  string session_id = 1;
  uint32 limit = 2;
  int64 after_timestamp = 3;
  map<string, string> filter = 4;
}

message GetMemoryResponse {
  repeated MemoryEntry entries = 1;
}

message ClearMemoryRequest {
  string session_id = 1;
}

message ClearMemoryResponse {
  bool success = 1;
  string message = 2;
}

message WatchMemoryRequest {
  string session_id = 1;
}

message MemoryEvent {
  string type = 1; // "added"
  MemoryEntry entry = 2;
}

// Cortex Session Messages
message CreateSessionRequest {
    optional string parent_session_id = 1;
}
message CreateSessionResponse {
    string session_id = 1;
}

message SnapshotSessionRequest {
  string session_id = 1;
  string path = 2;
}
message SnapshotSessionResponse {
  bool success = 1;
}

message LoadSessionRequest {
  string path = 1;
}
message LoadSessionResponse {
  string session_id = 1;
}

message CommitSessionRequest {
  string session_id = 1;
  string merge_strategy = 2; // "overwrite" (default), "bundle", "average"
}
message CommitSessionResponse {
  bool success = 1;
}

message DropSessionRequest {
  string session_id = 1;
}
message DropSessionResponse {
  bool success = 1;
}
