///|
/// PHI categories recognized by the built-in rules and extension points.
pub(all) enum PhiKind {
  PersonName
  IdNumber
  Phone
  Date
  Email
  Address
  MedicalRecord
  Insurance
  Organization
  Custom(String)
} derive(Debug, Eq)

///|
pub impl Show for PhiKind with fn output(self, logger) {
  match self {
    PersonName => logger.write_string("name")
    IdNumber => logger.write_string("id")
    Phone => logger.write_string("phone")
    Date => logger.write_string("date")
    Email => logger.write_string("email")
    Address => logger.write_string("address")
    MedicalRecord => logger.write_string("medical_record")
    Insurance => logger.write_string("insurance")
    Organization => logger.write_string("organization")
    Custom(v) => logger.write_string(v)
  }
}

///|
/// Replacement policy used when applying findings to text.
pub(all) enum ReplacementMode {
  Token
  PreserveLength
  Partial
  StableHash
} derive(Debug, Eq)

///|
/// A rule is deliberately data-shaped so downstream users can load or generate
/// domain rules without changing the scanning pipeline.
pub(all) struct Rule {
  id : String
  label : String
  kind : PhiKind
  pattern : String
  placeholder : String
  confidence : Int
  enabled : Bool
  contextual : Bool
} derive(Debug, Eq)

///|
pub(all) struct Finding {
  id : String
  kind : PhiKind
  label : String
  start : Int
  end : Int
  text : String
  replacement : String
  rule_id : String
  confidence : Int
} derive(Debug, Eq)

///|
pub(all) struct OffsetMap {
  original_start : Int
  original_end : Int
  replacement_start : Int
  replacement_end : Int
  finding_id : String
} derive(Debug, Eq)

///|
pub(all) struct AuditReport {
  input_length : Int
  output_length : Int
  finding_count : Int
  applied_count : Int
  counts : Map[String, Int]
  findings : Array[Finding]
  offsets : Array[OffsetMap]
} derive(Debug)

///|
pub(all) struct DeidResult {
  text : String
  findings : Array[Finding]
  offsets : Array[OffsetMap]
  audit : AuditReport
} derive(Debug)

///|
pub(all) struct DeidOptions {
  mode : ReplacementMode
  min_confidence : Int
  include_disabled_rules : Bool
} derive(Debug, Eq)

///|
pub fn DeidOptions::default() -> DeidOptions {
  { mode: Token, min_confidence: 60, include_disabled_rules: false }
}

///|
pub fn token_options(min_confidence? : Int = 60) -> DeidOptions {
  { mode: Token, min_confidence, include_disabled_rules: false }
}

///|
pub fn preserve_length_options(min_confidence? : Int = 60) -> DeidOptions {
  { mode: PreserveLength, min_confidence, include_disabled_rules: false }
}

///|
pub fn partial_options(min_confidence? : Int = 60) -> DeidOptions {
  { mode: Partial, min_confidence, include_disabled_rules: false }
}

///|
pub fn stable_hash_options(min_confidence? : Int = 60) -> DeidOptions {
  { mode: StableHash, min_confidence, include_disabled_rules: false }
}

///|
pub(all) struct ExternalEntity {
  kind : PhiKind
  label : String
  start : Int
  end : Int
  confidence : Int
  source : String
} derive(Debug, Eq)