// ============================================================
// Stable blackboard export helpers
// ============================================================

///|
/// Return a stable textual representation for logs and fixtures.
pub fn Value::to_text(self : Value) -> String {
  match self {
    Value::Bool(value) => "bool:\{value}"
    Value::Int(value) => "int:\{value}"
    Value::Double(value) => "double:\{value}"
    Value::Str(value) => "string:\{value}"
  }
}

///|
/// Export entries in insertion order as `key=value` lines.
pub fn Blackboard::to_text(self : Blackboard) -> String {
  let output = StringBuilder::new()
  for key in self.keys() {
    match self.get_value(key) {
      Some(value) => {
        output.write_string(key)
        output.write_string("=")
        output.write_string(value.to_text())
        output.write_string("\n")
      }
      None => ()
    }
  }
  output.to_string()
}

///|
/// Copy a selected set of keys into a fresh blackboard.
pub fn Blackboard::select(
  self : Blackboard,
  keys : Array[String],
) -> Blackboard {
  let result = Blackboard::new()
  for key in keys {
    match self.get_value(key) {
      Some(value) => result.set_value(key, value)
      None => ()
    }
  }
  result
}

///|
/// Remove all keys except the supplied allow-list.
pub fn Blackboard::retain(self : Blackboard, keys : Array[String]) -> Unit {
  let allowed : Map[String, Bool] = Map([])
  for key in keys {
    allowed[key] = true
  }
  let remove : Array[String] = []
  for key in self.keys() {
    if !allowed.contains(key) {
      remove.push(key)
    }
  }
  for key in remove {
    self.remove(key)
  }
}