// 输出层:Authentication-Results 头、text 与 json。
//
// 三种输出都来自同一份 AuthReport,因此不会出现「渲染和判定不一致」。

///|
fn json_escape(text : StringView) -> String {
  let out = StringBuilder()
  for c in text {
    match c {
      '"' => out.write_string("\\\"")
      '\\' => out.write_string("\\\\")
      '\n' => out.write_string("\\n")
      '\r' => out.write_string("\\r")
      '\t' => out.write_string("\\t")
      _ => out.write_char(c)
    }
  }
  out.to_string()
}

///|
/// 生成 RFC 8601 的 Authentication-Results 头(不含字段名)。
pub fn authentication_results(
  report : AuthReport,
  authserv_id : String,
) -> String {
  let parts : Array[String] = []
  for result in report.dkim {
    parts.push(
      "dkim=\{result.status.label()} header.d=\{result.domain} header.s=\{result.selector} (\{result.reason})",
    )
  }
  match report.spf {
    Some(result) =>
      parts.push(
        "spf=\{result.status.label()} smtp.mailfrom=\{result.domain} (\{result.mechanism})",
      )
    None => ()
  }
  match report.dmarc {
    Some(result) =>
      parts.push(
        "dmarc=\{result.status.label()} header.from=\{result.domain} (policy=\{result.policy}, disposition=\{result.disposition})",
      )
    None => ()
  }
  let out = StringBuilder()
  out.write_string(authserv_id)
  for part in parts {
    out.write_string(";\r\n\t")
    out.write_string(part)
  }
  out.to_string()
}

///|
/// 人类可读的 text 输出。
pub fn render_text(report : AuthReport) -> String {
  let out = StringBuilder()
  if report.dkim.length() == 0 {
    out.write_string("dkim: none\n")
  }
  for result in report.dkim {
    out.write_string(
      "dkim: \{result.status.label()} d=\{result.domain} s=\{result.selector}\n",
    )
    out.write_string("  reason: \{result.reason}\n")
    for item in result.evidence {
      out.write_string("  - \{item.label}: \{item.detail}\n")
    }
  }
  match report.spf {
    Some(result) => {
      out.write_string(
        "spf: \{result.status.label()} domain=\{result.domain}\n",
      )
      out.write_string("  mechanism: \{result.mechanism}\n")
      out.write_string("  reason: \{result.reason}\n")
      out.write_string(
        "  dns: \{result.dns_lookups} lookups, \{result.void_lookups} void\n",
      )
    }
    None => out.write_string("spf: not evaluated\n")
  }
  match report.dmarc {
    Some(result) => {
      out.write_string(
        "dmarc: \{result.status.label()} domain=\{result.domain}\n",
      )
      out.write_string(
        "  policy: \{result.policy}, disposition: \{result.disposition}\n",
      )
      out.write_string(
        "  aligned: dkim=\{result.dkim_aligned}, spf=\{result.spf_aligned}\n",
      )
      out.write_string("  reason: \{result.reason}\n")
    }
    None => out.write_string("dmarc: not evaluated\n")
  }
  out.to_string()
}

///|
/// 稳定的 json 输出,字段顺序固定,方便 CI 对拍。
pub fn render_json(report : AuthReport) -> String {
  let out = StringBuilder()
  out.write_string("{\"dkim\":[")
  for i in 0.. 0 {
      out.write_string(",")
    }
    let result = report.dkim[i]
    out.write_string("{\"domain\":\"\{json_escape(result.domain)}\"")
    out.write_string(",\"selector\":\"\{json_escape(result.selector)}\"")
    out.write_string(",\"algorithm\":\"\{json_escape(result.algorithm)}\"")
    out.write_string(",\"status\":\"\{result.status.label()}\"")
    out.write_string(",\"reason\":\"\{json_escape(result.reason)}\"}")
  }
  out.write_string("],\"spf\":")
  match report.spf {
    Some(result) => {
      out.write_string("{\"domain\":\"\{json_escape(result.domain)}\"")
      out.write_string(",\"identity\":\"\{json_escape(result.identity)}\"")
      out.write_string(",\"status\":\"\{result.status.label()}\"")
      out.write_string(",\"mechanism\":\"\{json_escape(result.mechanism)}\"")
      out.write_string(",\"reason\":\"\{json_escape(result.reason)}\"")
      out.write_string(",\"dns_lookups\":\{result.dns_lookups}")
      out.write_string(",\"void_lookups\":\{result.void_lookups}}")
    }
    None => out.write_string("null")
  }
  out.write_string(",\"dmarc\":")
  match report.dmarc {
    Some(result) => {
      out.write_string("{\"domain\":\"\{json_escape(result.domain)}\"")
      out.write_string(",\"status\":\"\{result.status.label()}\"")
      out.write_string(",\"policy\":\"\{json_escape(result.policy)}\"")
      out.write_string(
        ",\"disposition\":\"\{json_escape(result.disposition)}\"",
      )
      out.write_string(",\"dkim_aligned\":\{result.dkim_aligned}")
      out.write_string(",\"spf_aligned\":\{result.spf_aligned}")
      out.write_string(",\"reason\":\"\{json_escape(result.reason)}\"}")
    }
    None => out.write_string("null")
  }
  out.write_string("}")
  out.to_string()
}