///|
pub struct MailPolicy {
  max_parts : Int
  max_attachments : Int
  max_attachment_size : Int
  allow_html : Bool
} derive(Eq, Debug)

///|
pub struct PolicyViolation {
  code : String
  message : String
} derive(Eq, Debug)

///|
pub fn default_policy() -> MailPolicy {
  {
    max_parts: 100,
    max_attachments: 20,
    max_attachment_size: 10_000_000,
    allow_html: true,
  }
}

///|
pub fn strict_policy() -> MailPolicy {
  {
    max_parts: 20,
    max_attachments: 5,
    max_attachment_size: 1_000_000,
    allow_html: false,
  }
}

///|
pub fn check_policy(
  message : MailMessage,
  policy : MailPolicy,
) -> Array[PolicyViolation] {
  let out : Array[PolicyViolation] = []
  if part_count(message) > policy.max_parts {
    out.push({
      code: "parts.too_many",
      message: "message has too many MIME parts",
    })
  }
  if attachment_count(message) > policy.max_attachments {
    out.push({
      code: "attachments.too_many",
      message: "message has too many attachments",
    })
  }
  for item in attachment_infos(message) {
    if item.size > policy.max_attachment_size {
      out.push({ code: "attachment.too_large", message: item.filename })
    }
  }
  if !policy.allow_html && html_text(message) != "" {
    out.push({
      code: "html.disallowed",
      message: "HTML body is not allowed by policy",
    })
  }
  out
}

///|
pub fn has_policy_violation(
  violations : Array[PolicyViolation],
  code : String,
) -> Bool {
  for item in violations {
    if item.code == code {
      return true
    }
  }
  false
}