// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2026 clbbbb

///|
pub struct ReadmeAudit {
  has_title : Bool
  has_license : Bool
  has_install : Bool
  has_usage : Bool
  has_example : Bool
  mentioned_licenses : Array[String]
} derive(Debug, Eq)

///|
pub fn audit_readme(readme : String) -> ReadmeAudit {
  {
    has_title: readme_has_title(readme),
    has_license: readme_has_license_section(readme),
    has_install: readme_has_section(readme, "install") ||
    readme_has_section(readme, "installation"),
    has_usage: readme_has_section(readme, "usage") ||
    readme_has_section(readme, "example"),
    has_example: readme_has_code_block(readme),
    mentioned_licenses: mentioned_license_ids(readme),
  }
}

///|
pub fn readme_has_title(readme : String) -> Bool {
  for line in split_char(readme, '\n') {
    if trim_ascii(line).has_prefix("# ") {
      return true
    }
  }
  false
}

///|
pub fn readme_has_section(readme : String, title : String) -> Bool {
  let target = lower_ascii(title)
  for line in split_char(readme, '\n') {
    let clean = lower_ascii(trim_ascii(line))
    if clean.has_prefix("#") && clean.find(target) is Some(_) {
      return true
    }
  }
  false
}

///|
pub fn readme_has_license_section(readme : String) -> Bool {
  readme_has_section(readme, "license") ||
  lower_ascii(readme).find("license:") is Some(_)
}

///|
pub fn readme_has_code_block(readme : String) -> Bool {
  readme.find("```") is Some(_)
}

///|
pub fn mentioned_license_ids(readme : String) -> Array[String] {
  let lower = lower_ascii(readme)
  let rows : Array[String] = []
  for id in known_licenses() {
    match lower.find(lower_ascii(id)) {
      Some(_) => rows.push(id)
      None => ()
    }
  }
  unique_strings(rows)
}

///|
pub fn readme_audit_warnings(audit : ReadmeAudit) -> Array[String] {
  let rows : Array[String] = []
  if !audit.has_title {
    rows.push("README title is missing")
  }
  if !audit.has_license {
    rows.push("README license section is missing")
  }
  if !audit.has_install {
    rows.push("README install section is missing")
  }
  if !audit.has_usage {
    rows.push("README usage or example section is missing")
  }
  if !audit.has_example {
    rows.push("README runnable code block is missing")
  }
  rows
}

///|
pub fn readme_audit_report(readme : String) -> String {
  let audit = audit_readme(readme)
  let rows : Array[String] = [
    "title: " + bool_word(audit.has_title),
    "license section: " + bool_word(audit.has_license),
    "install section: " + bool_word(audit.has_install),
    "usage section: " + bool_word(audit.has_usage),
    "code example: " + bool_word(audit.has_example),
    "mentioned licenses: " + join_with(audit.mentioned_licenses, ","),
  ]
  push_section(rows, "README warnings", readme_audit_warnings(audit))
  join_lines(rows)
}

///|
pub fn readme_matches_package_license(
  readme : String,
  package_license : String,
) -> Bool {
  if package_license == "" || !is_valid(package_license) {
    false
  } else {
    let ids = mentioned_license_ids(readme)
    for id in licenses(parse_or_panic(package_license)) {
      if contains_string(ids, id) {
        return true
      }
    }
    false
  }
}