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

///|
pub struct LicenseProfile {
  id : String
  family : String
  osi : Bool
  copyleft : Bool
  risk : String
  note : String
} derive(Debug, Eq)

///|
pub fn license_profile(id : String) -> LicenseProfile {
  let canonical = canonical_license(id)
  {
    id: canonical,
    family: license_family(canonical),
    osi: is_osi_license(canonical),
    copyleft: is_copyleft_license(canonical),
    risk: license_risk(canonical),
    note: license_note(canonical),
  }
}

///|
pub fn license_family(id : String) -> String {
  let value = canonical_license(id)
  if value == "MIT" || value == "ISC" || value == "0BSD" || value == "Zlib" {
    "permissive"
  } else if value == "Apache-2.0" || value == "BSL-1.0" {
    "permissive-patent"
  } else if value == "BSD-2-Clause" || value == "BSD-3-Clause" {
    "permissive-notice"
  } else if value == "MPL-2.0" || value == "EPL-2.0" || value == "CDDL-1.0" {
    "file-level-copyleft"
  } else if value.has_prefix("LGPL") {
    "weak-copyleft"
  } else if value.has_prefix("GPL") {
    "strong-copyleft"
  } else if value == "CC0-1.0" || value == "Unlicense" {
    "public-domain-style"
  } else {
    "unknown"
  }
}

///|
pub fn license_risk(id : String) -> String {
  let family = license_family(id)
  if family == "unknown" {
    "unknown"
  } else if family == "strong-copyleft" {
    "high"
  } else if family == "weak-copyleft" || family == "file-level-copyleft" {
    "medium"
  } else {
    "low"
  }
}

///|
pub fn license_note(id : String) -> String {
  let value = canonical_license(id)
  if value == "MIT" {
    "short permissive license, keep copyright and license notice"
  } else if value == "Apache-2.0" {
    "permissive license with explicit patent grant and NOTICE handling"
  } else if value == "BSD-2-Clause" || value == "BSD-3-Clause" {
    "permissive BSD license, keep copyright and disclaimer"
  } else if value == "ISC" || value == "0BSD" || value == "Zlib" {
    "small permissive license commonly used by libraries"
  } else if value == "MPL-2.0" {
    "file-level copyleft, modified MPL files stay under MPL"
  } else if value == "EPL-2.0" {
    "file/module oriented copyleft used by Eclipse projects"
  } else if value.has_prefix("LGPL") {
    "weak copyleft, pay attention to linking and relinking obligations"
  } else if value.has_prefix("GPL") {
    "strong copyleft, distribution may require whole derivative source"
  } else if value == "CC0-1.0" || value == "Unlicense" {
    "public-domain-style terms, not always OSI-approved in this catalog"
  } else {
    "not in the compact catalog"
  }
}

///|
pub fn profile_row(id : String) -> String {
  let p = license_profile(id)
  p.id +
  "," +
  p.family +
  "," +
  bool_word(p.osi) +
  "," +
  bool_word(p.copyleft) +
  "," +
  p.risk
}

///|
pub fn profile_table(text : String) -> String {
  match parse(text).expr {
    Some(expr) => {
      let rows : Array[String] = ["license,family,osi,copyleft,risk"]
      for id in licenses(expr) {
        rows.push(profile_row(id))
      }
      join_lines(rows)
    }
    None => "error," + parse(text).error
  }
}

///|
pub fn bool_word(value : Bool) -> String {
  if value {
    "true"
  } else {
    "false"
  }
}

///|
pub fn highest_risk(text : String) -> String {
  match parse(text).expr {
    Some(expr) => {
      let mut result = "low"
      for id in licenses(expr) {
        let risk = license_risk(id)
        if risk == "unknown" {
          return "unknown"
        }
        if risk == "high" {
          result = "high"
        } else if risk == "medium" && result == "low" {
          result = "medium"
        }
      }
      result
    }
    None => "unknown"
  }
}