syntax = "proto3";

package flare.core.commands;

// ============================================================
// Flare IM 通信命令协议（精简版）
// 设计目标：
// 1. 结构简单明了
// 2. 去除重复命令
// 3. 保留系统命令、载荷命令、通知命令、自定义命令
// ============================================================

message Command {
  oneof type {
    SystemCommand       system       = 1; // 系统命令（连接、心跳、错误等）
    PayloadCommand      payload      = 2; // 载荷命令（message/event/ack/data）
    NotificationCommand notification = 3; // 通知命令（广播、用户状态等）
    CustomCommand       custom       = 4; // 自定义命令（业务扩展）
  }
}

// ------------------------------------------------------------
// 系统命令
// ------------------------------------------------------------
message SystemCommand {
  enum Type {
    UNSPECIFIED    = 0;
    CONNECT        = 1; // 客户端请求连接 / 握手（需要 format、metadata）
    CONNECT_ACK    = 2; // 服务端确认连接（需要 format、metadata）
    CLOSE          = 3; // 关闭连接（可选 message、metadata）
    PING           = 4; // 心跳请求（仅需 type）
    PONG           = 5; // 心跳响应（仅需 type）
    ERROR          = 6; // 错误通知（需要 message，可选 metadata）
    EVENT          = 7; // 系统事件（需要 message，可选 metadata、data）
    AUTH           = 8; // 鉴权请求（需要 metadata，可选 data）
    AUTH_ACK       = 9; // 鉴权响应（可选 message、metadata）
    KICKED         = 10; // 被踢下线（需要 message 说明原因，可选 metadata）
    NEGOTIATION_READY = 11; // 协商完成确认（客户端收到 CONNECT_ACK 后发送，表示已准备好使用协商好的加密方式）
  }

  // 序列化格式（仅在 CONNECT/CONNECT_ACK 时使用）
  enum SerializationFormat {
    PROTOBUF = 0; // Protobuf 序列化
    JSON     = 1; // JSON 序列化
  }

  Type type = 1;                       // 命令类型（必需）
  SerializationFormat format = 2;      // 序列化格式（仅 CONNECT/CONNECT_ACK）
  string message = 3;                  // 说明信息（ERROR、EVENT、CLOSE、AUTH_ACK）
  map<string, bytes> metadata = 4;     // 附加参数（CONNECT、AUTH等）
  bytes data = 5;                      // 数据载荷（EVENT、AUTH等）
  string compression = 6;              // 压缩算法（仅 CONNECT_ACK，必须是已注册的算法）
  string encryption = 7;               // 加密方式（仅 CONNECT_ACK，为未来扩展预留）
}

// ------------------------------------------------------------
// 载荷命令（信道层：在信道上传输的四类载荷）
// ------------------------------------------------------------
message PayloadCommand {
  enum Type {
    UNSPECIFIED = 0;
    MESSAGE     = 1; // 业务消息（需 ACK，有序）
    EVENT       = 2; // 事件（状态变更、通知等，可选 message_id/seq）
    ACK         = 3; // 确认（对 MESSAGE 或请求的确认）
    DATA        = 4; // 普通数据传输（无需 ACK）
  }

  Type type = 1;
  string message_id = 2;               // 消息/请求唯一 ID（MESSAGE/ACK 必填，EVENT 可选）
  bytes payload = 3;                   // 载荷内容
  map<string, bytes> metadata = 4;     // 元信息（统一为 bytes 类型）
  uint64 seq = 5;                      // 序列号（可用于有序传输，MESSAGE 常用）
}

// ------------------------------------------------------------
// 通知命令
// ------------------------------------------------------------
message NotificationCommand {
  enum Type {
    SYSTEM    = 0; // 系统通知（维护、更新等）
    BROADCAST = 1; // 广播消息
    ALERT     = 2; // 警告提示
    USER      = 3; // 用户状态变化
    CONNECTION = 4; // 连接事件（如重连）
  }

  Type type = 1;
  string title = 2;                     // 通知标题
  bytes content = 3;                    // 通知内容
  map<string, bytes> metadata = 4;      // 附加信息（跳转参数等，统一为bytes类型）
}

// ------------------------------------------------------------
// 自定义命令
// ------------------------------------------------------------
message CustomCommand {
  string name = 1;                      // 自定义命令名
  bytes data = 2;                       // 自定义数据内容（JSON、protobuf等）
  map<string, bytes> metadata = 3;      // 扩展元信息（统一为bytes类型）
}
