///|
fn split_lines(text : String) -> Array[String] {
  let mut count = 1
  for i in 0.. {
    while cursor < text.length() && text.unsafe_get(cursor) != (10).to_uint16() {
      cursor = cursor + 1
    }
    let line = text[start:cursor].to_owned()
    if cursor < text.length() {
      cursor = cursor + 1
    }
    start = cursor
    line
  })
}

///|
fn split_once(line : String, sep : Char) -> (String, String) {
  let sep = sep.to_int().to_uint16()
  for i in 0.. Array[Header] {
  let lines = split_lines(text)
  let mut count = 0
  for i in 0.. {
    while offset < lines.length() && trim_ascii(lines[offset]) == "" {
      offset = offset + 1
    }
    let (name, value) = split_once(lines[offset], ':')
    offset = offset + 1
    Header::new(name, value)
  })
}

///|
pub fn parse_method(value : String) -> HttpMethod {
  match ascii_lower(trim_ascii(value)) {
    "get" => Get
    "post" => Post
    "put" => Put
    "patch" => Patch
    "delete" => Delete
    other => Unknown(other)
  }
}

///|
pub fn request_from_parts(
  provider : String,
  method_text : String,
  path : String,
  body : String,
  received_at : Int,
  header_text : String,
) -> WebhookRequest {
  {
    provider,
    http_method: parse_method(method_text),
    path,
    body,
    received_at,
    headers: parse_headers(header_text),
    remote_ip: "",
  }
}

///|
pub fn raw_request_summary(
  request : WebhookRequest,
  profile : ProviderProfile,
) -> String {
  let builder = StringBuilder::new()
  builder.write_string(method_name(request.http_method))
  builder.write_string(" ")
  builder.write_string(request.path)
  builder.write_string(" provider=")
  builder.write_string(request.provider)
  builder.write_string(" event=")
  builder.write_string(provider_event_type(request, profile))
  builder.write_string(" id=")
  builder.write_string(provider_event_id(request, profile))
  builder.to_string()
}

///|
pub fn clone_with_body(
  request : WebhookRequest,
  body : String,
) -> WebhookRequest {
  { ..request, body, }
}

///|
pub fn clone_with_received_at(
  request : WebhookRequest,
  received_at : Int,
) -> WebhookRequest {
  { ..request, received_at, }
}

///|
pub fn headers_to_text(headers : Array[Header]) -> String {
  let builder = StringBuilder::new()
  for i in 0..