///|
fn same_name(a : String, b : String, dialect : Dialect) -> Bool {
  if dialect.case_sensitive {
    a == b
  } else {
    a.to_lower() == b.to_lower()
  }
}

///|
fn duplicate_diagnostics(
  nodes : Array[Node],
  dialect : Dialect,
) -> Array[Diagnostic] {
  let result : Array[Diagnostic] = []
  let seen : Map[(String, String), Span] = Map([])
  for node in nodes {
    if node.kind == Entry {
      let section = if dialect.case_sensitive {
        node.section
      } else {
        node.section.to_lower()
      }
      let key = if dialect.case_sensitive {
        node.key
      } else {
        node.key.to_lower()
      }
      match seen.get((section, key)) {
        Some(first) =>
          result.push({
            code: "INI009",
            severity: if dialect.duplicates == Reject {
              Error
            } else {
              Warning
            },
            message: "duplicate key; related span identifies first occurrence",
            span: node.key_span,
            related: Some(first),
          })
        None => seen.set((section, key), node.key_span)
      }
    }
  }
  result
}