// 公共数据类型。
//
// 本库刻意不依赖任何第三方包,所有判定都只基于输入字节,
// 因此同一份输入在任何后端上都会得到相同结果。

///|
/// 文件大类。
pub(all) enum Category {
  Image
  Document
  Archive
  Audio
  Video
  Executable
  Font
  Database
  Scientific
  Wasm
  Text
  Other
}

///|
/// 判定置信度。
///
/// - `Certain`:命中强签名,或容器结构可以明确消歧;
/// - `Probable`:弱签名、结构校验不完整或文本启发式;
/// - `Unknown`:没有足够证据,宁可返回未知也不猜。
///
/// 具体取值由 `confidence_of_score` 从证据评分推导。
pub(all) enum Confidence {
  Certain
  Probable
  Unknown
}

///|
/// 一种文件类型。
pub(all) struct FileType {
  /// 稳定的类型 id,例如 `png`、`docx`
  id : String
  /// IANA 风格的 MIME 类型
  mime : String
  /// 不带点号的推荐扩展名
  ext : String
  category : Category
}

///|
/// 一条判定证据。
///
/// 置信度不是人工标注的标签,而是由证据累加得到的评分:
/// 强魔数 90 分、弱魔数 20 分、结构验证 40~70 分、文本启发式 30 分;
/// 总分 ≥ 90 判 `Certain`,≥ 20 判 `Probable`,否则 `Unknown`。
pub(all) struct Evidence {
  /// 证据种类:`magic` / `structure` / `heuristic` / `rule`
  kind : String
  /// 人类可读描述
  label : String
  offset : Int
  matched_len : Int
  /// 该证据贡献的分值
  weight : Int
}

///|
/// 一次识别结果。
pub(all) struct Detection {
  /// 识别出的类型;`None` 表示未知
  file_type : FileType?
  confidence : Confidence
  /// 人类可读的证据说明(摘要)
  reason : String
  /// 主证据在输入中的偏移
  offset : Int
  /// 主证据的字节数
  matched_len : Int
  /// 存在歧义时的候选类型(例如 OLE2 容器)
  candidates : Array[FileType]
  /// 证据累加得到的评分(0~100)
  score : Int
  /// 完整证据链,按贡献顺序排列
  evidence : Array[Evidence]
}

///|
/// 由评分推导置信度。阈值是公开契约,不随调用点变化。
pub fn confidence_of_score(score : Int) -> Confidence {
  if score >= 90 {
    Certain
  } else if score >= 20 {
    Probable
  } else {
    Unknown
  }
}

///|
/// 大类名称。
pub fn category_name(category : Category) -> String {
  match category {
    Image => "image"
    Document => "document"
    Archive => "archive"
    Audio => "audio"
    Video => "video"
    Executable => "executable"
    Font => "font"
    Database => "database"
    Scientific => "scientific"
    Wasm => "wasm"
    Text => "text"
    Other => "other"
  }
}

///|
/// 置信度名称。
pub fn confidence_name(confidence : Confidence) -> String {
  match confidence {
    Certain => "certain"
    Probable => "probable"
    Unknown => "unknown"
  }
}

///|
/// 该类型是否属于文本大类。
pub fn is_text_category(file_type : FileType) -> Bool {
  match file_type.category {
    Text => true
    _ => false
  }
}