///|
pub struct AuthResult {
  auth_method : String
  result : String
  properties : Array[(String, String)]
} derive(Eq, Debug)

///|
pub struct AuthenticationResults {
  authserv_id : String
  results : Array[AuthResult]
} derive(Eq, Debug)

///|
pub fn parse_authentication_results(value : String) -> AuthenticationResults {
  let parts = split_char(value, ';')
  let authserv = if parts.length() > 0 { trim_ascii(parts[0]) } else { "" }
  let results : Array[AuthResult] = []
  let mut i = 1
  while i < parts.length() {
    let item = trim_ascii(parts[i])
    if item != "" {
      results.push(parse_auth_result_item(item))
    }
    i = i + 1
  }
  { authserv_id: authserv, results }
}

///|
fn parse_auth_result_item(item : String) -> AuthResult {
  let words = split_char(item, ' ')
  let first = if words.length() > 0 { words[0] } else { "" }
  let method_result = split_char(first, '=')
  let auth_method = if method_result.length() > 0 {
    lower_ascii(method_result[0])
  } else {
    ""
  }
  let result = if method_result.length() > 1 {
    lower_ascii(method_result[1])
  } else {
    ""
  }
  let props : Array[(String, String)] = []
  let mut i = 1
  while i < words.length() {
    match split_once(words[i], '=') {
      Some((k, v)) => props.push((lower_ascii(trim_ascii(k)), trim_ascii(v)))
      None => ()
    }
    i = i + 1
  }
  { auth_method, result, properties: props }
}

///|
pub fn authentication_results_from_message(
  message : MailMessage,
) -> Array[AuthenticationResults] {
  let out : Array[AuthenticationResults] = []
  for value in all_header_values(message.headers, "Authentication-Results") {
    out.push(parse_authentication_results(value))
  }
  out
}

///|
pub fn auth_method_result(
  auth : AuthenticationResults,
  auth_method : String,
) -> String {
  let target = lower_ascii(auth_method)
  for item in auth.results {
    if item.auth_method == target {
      return item.result
    }
  }
  ""
}

///|
pub fn has_auth_pass(message : MailMessage, auth_method : String) -> Bool {
  for auth in authentication_results_from_message(message) {
    if auth_method_result(auth, auth_method) == "pass" {
      return true
    }
  }
  false
}

///|
pub fn has_auth_fail(message : MailMessage, auth_method : String) -> Bool {
  for auth in authentication_results_from_message(message) {
    let result = auth_method_result(auth, auth_method)
    if result == "fail" || result == "softfail" || result == "permerror" {
      return true
    }
  }
  false
}

///|
pub fn auth_summary(message : MailMessage) -> String {
  let mut out = ""
  for auth in authentication_results_from_message(message) {
    if out != "" {
      out = out + "\n"
    }
    out = out + auth.authserv_id
    for item in auth.results {
      out = out + " " + item.auth_method + "=" + item.result
    }
  }
  out
}