///|
/// Accept header (RFC 9110 Section 12.5)
pub(all) struct Accept {
  items : Array[MediaRange]
} derive(Eq)

///|
pub fn Accept::parse(input : String) -> Result[Accept, AcceptError] {
  let s = acc_trim_string(input)
  if s.length() == 0 {
    return Err(Empty)
  }
  let parts = acc_split_with_quotes(s, 44) // ,
  let mut items : Array[MediaRange] = []
  let mut part_idx = 0
  while part_idx < parts.length() {
    let part = acc_trim_string(parts[part_idx])
    if part.length() > 0 {
      let parse_result = acc_parse_media_range_item(part)
      match parse_result {
        Ok(item) => {
          let new_items = []
          let mut idx = 0
          while idx < items.length() {
            new_items.push(items[idx])
            idx = idx + 1
          }
          new_items.push(item)
          items = new_items
        }
        Err(e) => return Err(e)
      }
    }
    part_idx = part_idx + 1
  }
  if items.length() == 0 {
    return Err(Empty)
  }
  Ok({ items, })
}

///|
pub fn Accept::items(self : Accept) -> Array[MediaRange] {
  self.items
}

///|
pub fn Accept::to_string(self : Accept) -> String {
  let strs = acc_map_items(self.items, fn(i) { i.to_string() })
  acc_join_strings(strs, ", ")
}

///|
/// Media range for Accept header
pub(all) struct MediaRange {
  media_type : String
  subtype : String
  parameters : Array[(String, String)]
  q : QValue
} derive(Eq)

///|
pub fn MediaRange::media_type(self : MediaRange) -> String {
  self.media_type
}

///|
pub fn MediaRange::subtype(self : MediaRange) -> String {
  self.subtype
}

///|
pub fn MediaRange::parameters(self : MediaRange) -> Array[(String, String)] {
  self.parameters
}

///|
pub fn MediaRange::qvalue(self : MediaRange) -> QValue {
  self.q
}

///|
pub fn MediaRange::to_string(self : MediaRange) -> String {
  let mut result = self.media_type + "/" + self.subtype
  let mut idx = 0
  while idx < self.parameters.length() {
    let (name, value) = self.parameters[idx]
    if acc_needs_quoting(value) {
      result = result + "; " + name + "=\"" + acc_escape_quotes(value) + "\""
    } else {
      result = result + "; " + name + "=" + value
    }
    idx = idx + 1
  }
  if self.q.value < 1000 {
    result = result + "; q=" + self.q.to_string()
  }
  result
}