///|
pub struct SessionInfo {
  id : String
  timeout_seconds : Int32
}

///|
pub fn parse_session(value : String) -> SessionInfo raise RtspError {
  let parts = value.split(";").to_array()
  let id = trim(parts[0].to_owned())
  require(
    id.length() > 0 && id.length() <= 256 && clean(id) && !id.contains(" "),
    "session id",
  )
  let mut timeout_seconds = 60
  let mut found = false
  for i = 1; i < parts.length(); i = i + 1 {
    let p = parts[i].split("=").to_array()
    if lower(trim(p[0].to_owned())) == "timeout" {
      require(!found && p.length() == 2, "session timeout")
      timeout_seconds = number(trim(p[1].to_owned()), 86400)
      require(timeout_seconds > 0, "zero timeout")
      found = true
    }
  }
  { id, timeout_seconds, }
}

///|
pub struct RtpInfo {
  url : String
  sequence : Int32?
  timestamp : UInt32?
}

///|
pub fn parse_rtp_info(
  value : String,
  base : String,
) -> Array[RtpInfo] raise RtspError {
  require(value.length() <= 8192, "RTP-Info length")
  let result = []
  for item in value.split(",") {
    require(result.length() < 16, "RTP-Info count")
    let fields : Map[String, String] = Map([])
    for field in item.split(";") {
      let p = field.split("=").to_array()
      require(p.length() >= 2, "RTP-Info field")
      let k = lower(trim(p[0].to_owned()))
      require(!fields.contains(k), "duplicate RTP-Info field")
      fields[k] = trim(p[1:].map(x => x.to_owned()).join("="))
    }
    let url = match fields.get("url") {
      Some(v) => resolve_control(base, v)
      None => raise Invalid("RTP-Info url")
    }
    let sequence = fields.get("seq").map(v => number(v, 65535))
    let timestamp = match fields.get("rtptime") {
      None => None
      Some(v) => {
        require(v.length() > 0 && v.length() <= 10, "rtptime length")
        let mut n = 0UL
        for c in v {
          require(c >= '0' && c <= '9', "rtptime digit")
          n = n * 10UL + (c.to_int() - 48).to_uint64()
          require(n <= 4294967295UL, "rtptime overflow")
        }
        Some(n.to_uint())
      }
    }
    result.push({ url, sequence, timestamp, })
  }
  result
}