///|
pub fn parse_dmarc(text : String) -> DmarcRecord {
  let raw = clean(text)
  let mut valid_version = false
  let mut policy = ""
  let mut subdomain_policy = ""
  let mut pct = 100
  let mut rua = ""
  let mut ruf = ""
  let mut alignment_spf = "r"
  let mut alignment_dkim = "r"
  let mut pct_valid = true

  for segment in raw.split(";") {
    let item = clean(segment.to_owned())
    if item.is_empty() {
      continue
    }
    let parts = item.split("=").to_array()
    if parts.length() < 2 {
      continue
    }
    let key = lower(parts[0].trim().to_owned())
    let value = parts[1].trim().to_owned()
    if key == "v" && lower(value) == "dmarc1" {
      valid_version = true
    } else if key == "p" {
      policy = lower(value)
    } else if key == "sp" {
      subdomain_policy = lower(value)
    } else if key == "pct" {
      match parse_digits(value) {
        Some(number) => pct = number
        None => pct_valid = false
      }
    } else if key == "rua" {
      rua = value
    } else if key == "ruf" {
      ruf = value
    } else if key == "aspf" {
      alignment_spf = lower(value)
    } else if key == "adkim" {
      alignment_dkim = lower(value)
    }
  }

  let findings = dmarc_findings(
    valid_version, policy, subdomain_policy, pct, pct_valid, rua, alignment_spf,
    alignment_dkim,
  )
  {
    raw,
    valid_version,
    policy,
    subdomain_policy,
    pct,
    rua_count: csv_count(rua),
    ruf_count: csv_count(ruf),
    alignment_spf,
    alignment_dkim,
    findings,
  }
}

///|
fn dmarc_findings(
  valid_version : Bool,
  policy : String,
  subdomain_policy : String,
  pct : Int,
  pct_valid : Bool,
  rua : String,
  alignment_spf : String,
  alignment_dkim : String,
) -> Array[PolicyFinding] {
  let findings = Array::new(capacity=10)
  if valid_version {
    findings.push(pass("dmarc.version", "DMARC version is present", "v=DMARC1"))
  } else {
    findings.push(
      fail(
        "dmarc.version", "DMARC version is missing", "A valid DMARC record must include v=DMARC1.",
        "", "Publish a DMARC TXT record at _dmarc.example.com.",
      ),
    )
  }
  if policy == "reject" {
    findings.push(
      pass("dmarc.policy", "DMARC rejects failing mail", "p=reject"),
    )
  } else if policy == "quarantine" {
    findings.push(
      warn(
        "dmarc.policy-quarantine", "DMARC quarantines failing mail", "Quarantine is useful, but reject gives clearer spoofing protection.",
        "p=quarantine", "Move to p=reject after reviewing aggregate reports.",
      ),
    )
  } else if policy == "none" {
    findings.push(
      warn(
        "dmarc.policy-none",
        "DMARC is monitor-only",
        "p=none collects reports but does not ask receivers to block abuse.",
        "p=none",
        "Use quarantine or reject after sender alignment is confirmed.",
        penalty=10,
      ),
    )
  } else if policy == "" {
    findings.push(
      fail(
        "dmarc.policy-missing", "DMARC policy is missing", "The required p tag is absent.",
        "", "Add p=none, p=quarantine or p=reject.",
      ),
    )
  } else {
    findings.push(
      fail(
        "dmarc.policy-invalid", "DMARC policy is invalid", "The p tag must be none, quarantine or reject.",
        policy, "Use a valid DMARC policy value.",
      ),
    )
  }
  if subdomain_policy == "" {
    findings.push(
      warn(
        "dmarc.subdomain-default", "DMARC has no explicit subdomain policy", "Subdomains inherit p, which may be fine but is easy to overlook.",
        "", "Add sp=reject or sp=quarantine when subdomain mail is known.",
      ),
    )
  } else if subdomain_policy == "reject" || subdomain_policy == "quarantine" {
    findings.push(
      pass(
        "dmarc.subdomain-policy",
        "DMARC subdomain policy is explicit",
        "sp=" + subdomain_policy,
      ),
    )
  } else if subdomain_policy == "none" {
    findings.push(
      warn(
        "dmarc.subdomain-none", "DMARC subdomain policy is monitor-only", "sp=none leaves subdomain abuse weakly handled.",
        "sp=none", "Use sp=reject when subdomains do not send mail.",
      ),
    )
  } else {
    findings.push(
      fail(
        "dmarc.subdomain-invalid", "DMARC subdomain policy is invalid", "The sp tag must be none, quarantine or reject.",
        subdomain_policy, "Use a valid sp value or remove the tag.",
      ),
    )
  }
  if !pct_valid || pct < 0 || pct > 100 {
    findings.push(
      fail(
        "dmarc.pct-invalid",
        "DMARC percentage is invalid",
        "pct must be an integer from 0 to 100.",
        pct.to_string(),
        "Use pct=100 for full enforcement.",
      ),
    )
  } else if pct < 100 {
    findings.push(
      warn(
        "dmarc.pct-partial",
        "DMARC enforcement is partial",
        "Only part of the mail stream is covered by policy.",
        "pct=" + pct.to_string(),
        "Use pct=100 after rollout.",
      ),
    )
  } else {
    findings.push(pass("dmarc.pct", "DMARC applies to all mail", "pct=100"))
  }
  if csv_count(rua) > 0 {
    findings.push(
      pass("dmarc.rua", "DMARC aggregate reporting is configured", rua),
    )
  } else {
    findings.push(
      warn(
        "dmarc.rua-missing", "DMARC aggregate reporting is missing", "Without rua, operators cannot observe legitimate sender drift.",
        "", "Add a rua=mailto: address for aggregate reports.",
      ),
    )
  }
  if alignment_spf == "s" || alignment_spf == "r" {
    findings.push(
      pass("dmarc.aspf", "SPF alignment mode is valid", alignment_spf),
    )
  } else {
    findings.push(
      fail(
        "dmarc.aspf-invalid", "SPF alignment mode is invalid", "aspf must be r or s.",
        alignment_spf, "Use aspf=r or aspf=s.",
      ),
    )
  }
  if alignment_dkim == "s" || alignment_dkim == "r" {
    findings.push(
      pass("dmarc.adkim", "DKIM alignment mode is valid", alignment_dkim),
    )
  } else {
    findings.push(
      fail(
        "dmarc.adkim-invalid", "DKIM alignment mode is invalid", "adkim must be r or s.",
        alignment_dkim, "Use adkim=r or adkim=s.",
      ),
    )
  }
  findings
}