syntax = "proto3";
// import "google/protobuf/descriptor.proto";

// option (zhi_track_pb_version) = "1.0.14";

message DeviceInfo {
  // 设备厂商
  string brand = 1;
  // 设备型号
  string device_model = 2;
  // 屏幕分辨率， iOS 可以缺省
  string screen_resolution = 3;
  // 客户端类型，如 iPhone， iPad， Android， Harmony
  ClientType client_type = 4;
  // 系统名称 (iOS/Android/HarmonyOS)
  string os_name = 5;
  // 系统版本
  string os_version = 6;
  // 是否越狱
  bool is_jailbroken = 7;
  // 获取当前显示的语言(如果没有当前语言支持，则显示默认语言) like "zh'
  string language = 8;
  // 网络接入方式
  NetworkType network_type = 9;
  // 蜂窝网络类型 (network_type = NT_mobile 时有效)
  MobileNetworkType mobile_network_type = 10;
  // 剩余电量（取值 -1 到 100，获取不到则传入 -1）
  int32 remaining_battery = 11;
  // 是否正在充电
  bool is_charging = 12;
  // push侧生成的用 于发push的设备 标识
  string push_uuid = 13;
  // 设备时区
  string timezone = 14;
  // 系统配置的语言和地区 like "zh-Hans-CN"
  string locale = 15;
  // 设备 id 信息
  DeviceIDSet device_id_set = 16;

  // 手机网络接入方式
  enum NetworkType {
    // 未知网络类型
    NT_unknown = 0;
    // 无网络
    NT_not_reachable = 1;
    // WIFI
    NT_WIFI = 2;
    // 移动网络
    NT_mobile = 3;
    // 以太网
    NT_ethernet = 4;
  }

  // 蜂窝网络类型
  enum MobileNetworkType {
    // 未知网络类型 - Unknown
    MNT_UNKNOWN = 0;

    // 2G网络类型 - GPRS
    MNT_GPRS = 1;
    // 2G网络类型 - EDGE
    MNT_EDGE = 2;
    // 2G网络类型 - IDEN
    MNT_IDEN = 3;
    // 2G网络类型 - GSM
    MNT_GSM = 4;

    // 3G网络类型 - UMTS same with WCDMA
    MNT_UMTS = 5;
    // 3G网络类型 - CDMA
    MNT_CDMA = 6;
    // 3G网络类型 - EVDO_0
    MNT_EVDO_0 = 7;
    // 3G网络类型 - EVDO_A
    MNT_EVDO_A = 8;
    // 3G网络类型 - 1xRTT
    MNT_1xRTT = 9;
    // 3G网络类型 - HSDPA
    MNT_HSDPA = 10;
    // 3G网络类型 - HSUPA
    MNT_HSUPA = 11;
    // 3G网络类型 - HSPA
    MNT_HSPA = 12;
    // 3G网络类型 - EVDO_B
    MNT_EVDO_B = 13;
    // 3G网络类型 - EHRPD
    MNT_EHRPD = 14;
    // 3G网络类型 - HSPAP
    MNT_HSPAP = 15;
    // 3G网络类型 - TD_SCDMA
    MNT_TD_SCDMA = 16;

    // 4G网络类型 - LTE
    MNT_LTE = 17;
    // 4G网络类型 - IWLAN
    MNT_IWLAN = 18;
    // 4G网络类型 - LTE_CA
    MNT_LTE_CA = 19;

    // 5G网络类型 - NRNSA
    MNT_NRNSA = 20;
    // 5G网络类型 - NR
    MNT_NR = 21;
  }

  enum ClientType {
    unknown = 0;
    iPhone = 1;
    iPad = 2;
    // Android 没有直接的 API 能区分是手机还是平板，所以这里统称 AndroidDevice
    AndroidDevice = 3;
    // Harmony 手机
    HarmonyPhone = 4;
    // Harmony 平板
    HarmonyTablet = 5;
  }
}


// 各类设备 ID
message DeviceIDSet {
  // iOS 设备广告标识符
  string idfa = 1;
  // iOS 供应商标识符
  string idfv = 2;
  // Android 设备广告标识符
  string oaid = 3;
  // Android 设备标识符
  string android_id = 4;
  // 鸿蒙设备标识符
  string hm_device_id = 5;
  // 客户端本地发码的设备唯一标识符
  string local_id = 6;
  // 设备唯一 id，通过发码 SDK 获取
  string client_id = 7;
}

// 跟踪在线广告活动的相关信息
message UtmInfo {
  // 指定广告活动的关键字
  string utm_term = 1;
  // 指定用于标识广告系列的名称
  string utm_campaign = 2;
  // 指定广告媒介，如 CPC、banner、email
  string utm_medium = 3;
  //  指定广告的具体内容，如广告位
  string utm_content = 4;
  // 指定流量来源，如搜索引擎、广告平台名称
  string utm_source = 5;
}

message SourceInfo {
  // APP 名称
  string app_name = 1;
  // 包名
  string package_name = 2;
  // 打包模式
  BuildMode build_mode = 3;
  // 客户端下载渠道
  string download_channel = 4;

  enum BuildMode {
    // 未知
    build_mode_unknown = 0;
    // 开发模式
    dev = 1;
    // 内测模式
    beta = 2;
    // 灰度模式
    gray = 3;
    // 线上模式
    online = 4;
  }
}

message SessionInfo {
  string session_id = 1;
  // 客户端启动渠道
  OpenType open_type = 2;
  // 如果通过 push 打开的 APP，则填充推送 ID
  string push_id = 3;
  // 如果是外链打开的，则传入 open_url
  string open_url = 4;
  // utm 信息， 通过 openurl 解析得到
  UtmInfo utm = 5;
  // 分享链接的设备标识，通过 openurl 解析得到
  string sunionid = 6;
  // 分享链接的用户账号，通过 openurl 解析得到
  string suid = 7;

  enum OpenType {
    // 未知
    open_type_unknown = 0;
    // 点击 icon 直接打开
    icon = 1;
    // 点击推送打开
    push = 2;
    // 外链打开
    scheme = 3;
  }
}

message VersionInfo {
  // 打包版本号
  string build_version = 1;
  // app 外显版本
  string app_version = 2;
  // SDK 版本
  string sdk_version = 3;
  // PB 版本
  string protobuf_version = 4;
}

message Event {
  // 事件序列号，sessionid 更新 时，sequence 归零
  uint32 sequence = 1;
  // 事件全局序列号，一直递增的事件 序列号 不会随 sessionId 更新而归零
  uint32 global_sequence = 2;
  // 当前 app 状态 （前台 / 后台）
  ApplicationState application_state = 3;
  // 业务线 必填，每个埋点都应该有自己的业务归属方。
  string business_unit = 4;
  // 事件类型
  EventType event_type = 5;
  // 如果事件类型是 ubc（扩展类型的事件），则填充 ubc 的具体类型，字符串标识即可
  string ubc_type = 6;
  // 事件唯一标识 (时空唯一，每个事件均不同)
  string event_uuid = 7;
  // 开发技术栈
  DevelopmentStackType dev_stack = 8;
  TimeInfo time = 9;
  // 是否是 SDK 自动上报的事件
  bool isauto = 10;
  // 页面信息（App 级别事件留空，其它事件均携带）
  PageInfo page = 11;
  // 模块信息（App 级别和页面级别事件留空）
  ModuleInfo module = 12;
  // 是否是 SDK 自动拼装的 page_info (针对模块事件)
  bool auto_page_info = 13;

  // 当前应用状态枚举定义
  enum ApplicationState {
    // 未知
    app_state_unknown = 0;
    // 活跃状态
    app_state_active = 1;
    // 不可交互状态
    app_state_inactive = 2;
    // 后台
    app_state_background = 3;
  }
  // 事件类型枚举定义
  enum EventType {
    // 未知
    event_type_unknown = 0;
    // 应用启动
    app_start = 1;
    // 应用失活
    app_inactive = 2;
    // 应用崩溃
    app_crash = 3;
    // 应用被杀死
    app_exit = 4;
    // 页面展示
    page_show = 5;
    // 页面内容加载，通常在异步网络之后上报，非必须上报
    page_content_load = 6;
    // 页面消失
    page_disappear = 7;
    // 模块展示
    module_show = 8;
    // 模块消失
    module_disappear = 9;
    // 模块点击
    module_click = 10;
    // 模块滑动
    module_slide = 11;
    // 模块编辑
    module_edit = 12;
    // 模块长按
    module_long_press = 13;
    // 模块双击
    module_double_click = 14;
    // 订单事件
    order = 15;
    // 支付事件
    pay = 16;
    // 用户行为补充事件
    user_behavior_complement = 17;
    // 状态检测（技术类埋点/非用户行为类埋点）
    status_check = 18;
  }

  enum DevelopmentStackType {
    // 未知
    dev_stack_unknown = 0;
    // 原生
    dev_stack_native = 1;
    // 混合
    dev_stack_hybrid = 2;
    // RN
    dev_stack_react_native = 3;
    // Flutter
    dev_stack_flutter = 4;
  }
}

message PageInfo {
  // 页面唯一标识
  string identifier = 1;
  // 上个页面标识
  string refer_identifier = 2;
  // 一次页面访问的标识 （每一次页面访问，都会生成一个新的requestid）
  string request_id = 3;
  // 上一个页面的 request_id
  string refer_request_id = 4;
  // 端上实现时的类名（主要用于跟踪技术问题）
  string class_name = 5;
  // 页面扩展参数
  map<string, string> extras = 6;
}

message ModuleInfo {
  // 模块唯一标识 （id=identifer 代表的是英文标识符，不是数字）
  string module_id = 1;
  // 一次模块展示的标识（每一次模块展示，都会生成一个新的requestid）
  string request_id = 2;
  // 模块扩展参数
  map<string, string> extras = 3;
}

message TimeInfo {
  // 事件发生时的客户端时间（本地时间戳）
  uint64 client_time = 1;
  // 客户端同步的服务器端时间(通过 NTP 机制同步; 还未获取到时，取客户端时间)
  uint64 sync_time = 2;
  // 事件发送时间（本地时间戳）
  uint64 send_time = 3;
  // 事件发送时间（通过 NTP 机制同步; 还未获取到时，取客户端时间）
  uint64 sync_send_time = 4;
  // 是否已同步 NTP 时间
  bool sync_time_done = 5;
}

message UserInfo {
  // 用户唯一标识
  string identifier = 1;
  // 用户类别
  UserType type = 2;
  // 用户扩展信息
  map<string, string> extras = 3;

  enum UserType {
    // 未知
    user_type_unknown = 0;
    // 注册用户
    user_type_user = 1;
    // 访客
    user_type_guest = 2;
    // 企业
    user_type_organization = 3;
    // vip
    user_type_vip = 4;
  }
}

message ZAInfo {
  // 从知乎账号组件获取的字段 member_hash_id
  string member_hash_id = 1;
  // ZASDK 维护的在屏会话id
  string client_open_session = 2;
  // ZASDK 维护的 sessionID，每次冷启时重置
  string session_id = 3;
}

message ZhiTrack {
  // 设备信息
  DeviceInfo device = 1;
  // 来源信息（包名，下载渠道等）
  SourceInfo source = 2;
  // 版本信息
  VersionInfo versions = 3;
  // 用户信息
  UserInfo user_info = 4;
  // 会话信息，主要针对一次会话周期内的事件所携带的信息
  SessionInfo session = 5;
  // 全局扩展信息（例如针对特殊版本的标记，后续需要平台配合登记管理）
  map<string, string> sys_extras = 6;
  // 环境信息相同的事件集合，合并上报
  repeated Event events = 7;
  // 公考 AI 课已使用 ZA 进行了数据上报，这里是与 ZA 互通的相关信息，如果是一个全新的业务接入 ZT，可忽略该部分内容
  ZAInfo za_info = 8;
}


/// 用于批量上报 端上最终将埋点进行合并上报，这里出现多个元素，代表有多种不同环境信息的事件集合
message ZhiTrackPackage {
  repeated ZhiTrack zhi_tracks = 1;
}


/// 定义文件级别的扩展信息，这里添加版本号扩展，用来配合管理 pb 本身的版本。
// extend google.protobuf.FileOptions {
//   optional string zhi_track_pb_version = 50000;
// }
