///|
pub struct Limitation {
  area : String
  detail : String
  planned : Bool
} derive(Eq, Debug)

///|
pub fn known_limitations() -> Array[Limitation] {
  [
    limitation(
      "charset", "non-UTF-8 charset transcoding is not implemented yet", true,
    ),
    limitation(
      "encoded-words", "adjacent encoded-word whitespace normalization is intentionally conservative",
      true,
    ),
    limitation(
      "addresses", "group syntax and comments in address lists are parsed only in simple form",
      true,
    ),
    limitation(
      "mime", "streaming parsing for very large attachments is not implemented yet",
      true,
    ),
    limitation(
      "html", "HTML text extraction is a lightweight tag stripper, not a full HTML parser",
      true,
    ),
    limitation(
      "dates", "date parsing extracts common RFC 5322 fields but does not validate time zones deeply",
      true,
    ),
    limitation(
      "dsn", "delivery-status parsing covers common recipient blocks but not every extension field",
      true,
    ),
    limitation(
      "security", "risk scoring is heuristic and should not be used as the only anti-abuse signal",
      false,
    ),
    limitation(
      "json", "JSON export is stable text rendering, not a general JSON AST encoder",
      false,
    ),
    limitation(
      "attachments", "binary attachment bytes are represented as decoded text for the MVP",
      true,
    ),
  ]
}

///|
pub fn limitation(area : String, detail : String, planned : Bool) -> Limitation {
  { area, detail, planned }
}

///|
pub fn planned_limitation_count() -> Int {
  let mut count = 0
  for item in known_limitations() {
    if item.planned {
      count = count + 1
    }
  }
  count
}

///|
pub fn limitation_markdown() -> String {
  let mut out = "## Known Limitations\n"
  for item in known_limitations() {
    out = out + "- " + item.area + ": " + item.detail
    if item.planned {
      out = out + " (planned)"
    }
    out = out + "\n"
  }
  out
}

///|
pub fn roadmap_summary() -> String {
  "known_limitations=" +
  known_limitations().length().to_string() +
  " planned=" +
  planned_limitation_count().to_string()
}

///|
pub struct ReleaseCheck {
  name : String
  passed : Bool
  note : String
} derive(Eq, Debug)

///|
pub fn release_checks() -> Array[ReleaseCheck] {
  [
    release_check(
      "parse.simple", true, "plain .eml messages parse into MailMessage",
    ),
    release_check(
      "parse.multipart", true, "multipart/alternative and multipart/mixed are covered",
    ),
    release_check(
      "decode.transfer", true, "base64 and quoted-printable transfer encodings are covered",
    ),
    release_check(
      "extract.text", true, "plain and html body extraction are available",
    ),
    release_check(
      "extract.attachments", true, "attachment names, sizes, and content types are exposed",
    ),
    release_check(
      "lint", true, "broken MIME and risky attachment diagnostics are available",
    ),
    release_check(
      "security", true, "authentication and phishing-like signals are available",
    ),
    release_check(
      "corpus", true, "non-repeated realistic corpus fixtures are included",
    ),
    release_check("tests", true, "core workflows are covered by MoonBit tests"),
    release_check(
      "streaming", false, "streaming binary attachment parsing is planned after MVP",
    ),
  ]
}

///|
pub fn release_check(
  name : String,
  passed : Bool,
  note : String,
) -> ReleaseCheck {
  { name, passed, note }
}

///|
pub fn release_ready() -> Bool {
  for item in release_checks() {
    if !item.passed && item.name != "streaming" {
      return false
    }
  }
  true
}

///|
pub fn release_check_markdown() -> String {
  let mut out = "## Release Checks\n"
  for item in release_checks() {
    let mark = if item.passed { "pass" } else { "planned" }
    out = out + "- " + mark + " " + item.name + ": " + item.note + "\n"
  }
  out
}