///|
pub struct ReceivedHop {
  from_host : String
  by_host : String
  protocol : String
  id : String
  date : String
  raw : String
} derive(Eq, Debug)

///|
pub fn received_hops(message : MailMessage) -> Array[ReceivedHop] {
  let out : Array[ReceivedHop] = []
  for value in all_header_values(message.headers, "Received") {
    out.push(parse_received(value))
  }
  out
}

///|
pub fn parse_received(value : String) -> ReceivedHop {
  let date_split = split_once(value, ';')
  let front = match date_split {
    Some((left, _)) => left
    None => value
  }
  let date = match date_split {
    Some((_, right)) => trim_ascii(right)
    None => ""
  }
  {
    from_host: token_after(front, "from"),
    by_host: token_after(front, "by"),
    protocol: token_after(front, "with"),
    id: token_after(front, "id"),
    date,
    raw: value,
  }
}

///|
fn token_after(input : String, keyword : String) -> String {
  let words = split_char(input, ' ')
  let target = lower_ascii(keyword)
  let mut i = 0
  while i + 1 < words.length() {
    if lower_ascii(trim_ascii(words[i])) == target {
      return trim_ascii(words[i + 1])
    }
    i = i + 1
  }
  ""
}

///|
pub fn first_received_by(message : MailMessage) -> String {
  let hops = received_hops(message)
  if hops.length() > 0 {
    hops[0].by_host
  } else {
    ""
  }
}

///|
pub fn last_received_from(message : MailMessage) -> String {
  let hops = received_hops(message)
  if hops.length() > 0 {
    hops[hops.length() - 1].from_host
  } else {
    ""
  }
}

///|
pub fn received_path_summary(message : MailMessage) -> String {
  let mut out = ""
  let mut i = 0
  for hop in received_hops(message) {
    if i > 0 {
      out = out + " -> "
    }
    if hop.from_host != "" {
      out = out + hop.from_host
    }
    if hop.by_host != "" {
      out = out + "/" + hop.by_host
    }
    i = i + 1
  }
  out
}