///|
pub fn Model::schema(self : Model) -> String {
  self.header.schema_identifiers.get(0).unwrap_or("unknown")
}

///|
pub fn Model::products(self : Model) -> Array[Product] {
  extract_products(self.index())
}

///|
pub fn Model::property_sets(
  self : Model,
) -> Array[PropertySet] raise ParseError {
  all_property_sets(self.index())
}

///|
pub fn Model::summary(self : Model) -> ModelSummary {
  let index = self.index()
  let products = extract_products(index)
  let spatial_count = spatial_roots(index).fold(init=0, (count, root) => {
    count + flatten_spatial(root).length()
  })
  {
    schema: self.schema(),
    entity_count: self.entity_count(),
    product_count: products.length(),
    property_set_count: index.ids_named("IFCPROPERTYSET").length(),
    geometry_count: geometry_entities(index).length(),
    spatial_count,
  }
}

///|
pub fn Model::entity_names(self : Model) -> Array[String] {
  self.entities.map(entity => entity.name)
}

///|
pub fn Model::filter_entities(
  self : Model,
  filter : EntityFilter,
) -> Array[Entity] {
  match filter {
    All => self.entities
    Name(name) =>
      self.entities.filter(entity => entity.name.to_upper() == name.to_upper())
    Prefix(prefix) =>
      self.entities.filter(entity => {
        entity.name.to_upper().has_prefix(prefix.to_upper())
      })
    ProductOnly =>
      self.entities.filter(entity => is_product_entity(entity.name))
  }
}