/**
 * Visitor.ets
 *
 * Visitor 模式接口定义 - SwiftProtobuf 核心架构
 *
 * SwiftProtobuf 设计理念:
 * "Conceptually, serializers create visitor objects that are
 *  then passed recursively to every message and field via generated
 *  traverse methods."
 *
 * 用于将消息遍历与格式编码分离,支持:
 * - Binary 编码(Protobuf wire format)
 * - JSON 编码(Protobuf JSON mapping)
 * - Hash 计算
 * - Text format
 * - 任何自定义格式
 *
 * Version: 1.0.0
 * ArkTS 2025 兼容
 */

import { Message } from './Message'

/**
 * 字段访问者接口
 *
 * 每个 visit 方法对应一种字段类型,Visitor 实现类负责具体的格式编码逻辑。
 * 消息类通过 traverse() 方法遍历所有字段,调用相应的 visit 方法。
 */
export interface Visitor {
  // ========== 标量字段 ==========

  /**
   * 访问 int32 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitInt32(value: number, fieldNumber: number): void

  /**
   * 访问 int64 字段
   * @param value 字段值(使用 bigint)
   * @param fieldNumber proto 字段编号
   */
  visitInt64(value: bigint, fieldNumber: number): void

  /**
   * 访问 uint32 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitUint32(value: number, fieldNumber: number): void

  /**
   * 访问 uint64 字段
   * @param value 字段值(使用 bigint)
   * @param fieldNumber proto 字段编号
   */
  visitUint64(value: bigint, fieldNumber: number): void

  /**
   * 访问 sint32 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitSint32(value: number, fieldNumber: number): void

  /**
   * 访问 sint64 字段
   * @param value 字段值(使用 bigint)
   * @param fieldNumber proto 字段编号
   */
  visitSint64(value: bigint, fieldNumber: number): void

  /**
   * 访问 fixed32 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitFixed32(value: number, fieldNumber: number): void

  /**
   * 访问 fixed64 字段
   * @param value 字段值(使用 bigint)
   * @param fieldNumber proto 字段编号
   */
  visitFixed64(value: bigint, fieldNumber: number): void

  /**
   * 访问 sfixed32 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitSfixed32(value: number, fieldNumber: number): void

  /**
   * 访问 sfixed64 字段
   * @param value 字段值(使用 bigint)
   * @param fieldNumber proto 字段编号
   */
  visitSfixed64(value: bigint, fieldNumber: number): void

  /**
   * 访问 string 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitString(value: string, fieldNumber: number): void

  /**
   * 访问 bytes 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitBytes(value: Uint8Array, fieldNumber: number): void

  /**
   * 访问 bool 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitBool(value: boolean, fieldNumber: number): void

  /**
   * 访问 float 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitFloat(value: number, fieldNumber: number): void

  /**
   * 访问 double 字段
   * @param value 字段值
   * @param fieldNumber proto 字段编号
   */
  visitDouble(value: number, fieldNumber: number): void

  // ========== 枚举字段 ==========

  /**
   * 访问 enum 字段
   * @param value 枚举值(数字)
   * @param fieldNumber proto 字段编号
   */
  visitEnum(value: number, fieldNumber: number): void

  // ========== 嵌套消息(自动递归) ==========

  /**
   * 访问嵌套消息字段
   *
   * ⭐ 核心方法:Visitor 负责自动递归处理
   *
   * @param value 嵌套消息对象
   * @param fieldNumber proto 字段编号
   */
  visitMessage(value: Message, fieldNumber: number): void

  // ========== Repeated 字段 ==========

  /**
   * 访问 repeated int32 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedInt32(value: number[], fieldNumber: number): void

  /**
   * 访问 repeated int64 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedInt64(value: bigint[], fieldNumber: number): void

  /**
   * 访问 repeated uint32 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedUint32(value: number[], fieldNumber: number): void

  /**
   * 访问 repeated uint64 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedUint64(value: bigint[], fieldNumber: number): void

  /**
   * 访问 repeated sint32 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedSint32(value: number[], fieldNumber: number): void

  /**
   * 访问 repeated sint64 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedSint64(value: bigint[], fieldNumber: number): void

  /**
   * 访问 repeated fixed32 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedFixed32(value: number[], fieldNumber: number): void

  /**
   * 访问 repeated fixed64 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedFixed64(value: bigint[], fieldNumber: number): void

  /**
   * 访问 repeated sfixed32 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedSfixed32(value: number[], fieldNumber: number): void

  /**
   * 访问 repeated sfixed64 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedSfixed64(value: bigint[], fieldNumber: number): void

  /**
   * 访问 repeated string 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedString(value: string[], fieldNumber: number): void

  /**
   * 访问 repeated bytes 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedBytes(value: Uint8Array[], fieldNumber: number): void

  /**
   * 访问 repeated bool 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedBool(value: boolean[], fieldNumber: number): void

  /**
   * 访问 repeated float 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedFloat(value: number[], fieldNumber: number): void

  /**
   * 访问 repeated double 字段
   * @param value 字段值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedDouble(value: number[], fieldNumber: number): void

  /**
   * 访问 repeated enum 字段
   * @param value 枚举值数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedEnum(value: number[], fieldNumber: number): void

  /**
   * 访问 repeated message 字段
   * @param value 消息对象数组
   * @param fieldNumber proto 字段编号
   */
  visitRepeatedMessage(value: Message[], fieldNumber: number): void

  // ========== Map 字段 ==========
  // Map 在 protobuf 中编码为 repeated Entry<K, V>
  // Visitor 需要处理 Map 的特殊编码逻辑

  /**
   * 访问 map<string, int32> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapStringInt32(value: Map<string, number>, fieldNumber: number): void

  /**
   * 访问 map<string, int64> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapStringInt64(value: Map<string, bigint>, fieldNumber: number): void

  /**
   * 访问 map<string, string> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapStringString(value: Map<string, string>, fieldNumber: number): void

  /**
   * 访问 map<string, bytes> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapStringBytes(value: Map<string, Uint8Array>, fieldNumber: number): void

  /**
   * 访问 map<string, bool> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapStringBool(value: Map<string, boolean>, fieldNumber: number): void

  /**
   * 访问 map<string, message> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapStringMessage(value: Map<string, Message>, fieldNumber: number): void

  /**
   * 访问 map<int32, int32> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapInt32Int32(value: Map<number, number>, fieldNumber: number): void

  /**
   * 访问 map<int32, string> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapInt32String(value: Map<number, string>, fieldNumber: number): void

  /**
   * 访问 map<int32, message> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapInt32Message(value: Map<number, Message>, fieldNumber: number): void

  /**
   * 访问 map<int64, int64> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapInt64Int64(value: Map<bigint, bigint>, fieldNumber: number): void

  /**
   * 访问 map<int64, string> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapInt64String(value: Map<bigint, string>, fieldNumber: number): void

  /**
   * 访问 map<int64, message> 字段
   * @param value Map 对象
   * @param fieldNumber proto 字段编号
   */
  visitMapInt64Message(value: Map<bigint, Message>, fieldNumber: number): void

  // 注意:还有很多其他 map 类型组合(如 bool 作为 key 等)
  // 代码生成器需要根据实际 proto 定义生成相应的 visit 调用
}