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

///|
pub struct CompatibilityCell {
  left : String
  right : String
  compatible : Bool
  reason : String
} derive(Debug, Eq)

///|
pub fn compatibility_cell(
  left : String,
  right : String,
  compatible : Bool,
  reason : String,
) -> CompatibilityCell {
  { left, right, compatible, reason }
}

///|
pub fn license_pair_compatibility(
  left : String,
  right : String,
) -> CompatibilityCell {
  let a = canonical_license(left)
  let b = canonical_license(right)
  if a == b {
    compatibility_cell(a, b, true, "same license")
  } else if !is_known_license(a) || !is_known_license(b) {
    compatibility_cell(a, b, false, "unknown license requires manual review")
  } else if (a == "Apache-2.0" && b == "GPL-2.0-only") ||
    (b == "Apache-2.0" && a == "GPL-2.0-only") {
    compatibility_cell(
      a, b, false, "Apache-2.0 and GPL-2.0-only are usually incompatible",
    )
  } else if (a == "CDDL-1.0" && license_family(b) == "strong-copyleft") ||
    (b == "CDDL-1.0" && license_family(a) == "strong-copyleft") {
    compatibility_cell(
      a, b, false, "CDDL with GPL-style copyleft needs legal review",
    )
  } else if license_risk(a) == "high" || license_risk(b) == "high" {
    compatibility_cell(a, b, false, "strong copyleft combination needs review")
  } else {
    compatibility_cell(a, b, true, "no compact-catalog conflict")
  }
}

///|
pub fn compatibility_matrix(ids : Array[String]) -> Array[CompatibilityCell] {
  let rows : Array[CompatibilityCell] = []
  let unique = unique_strings(ids)
  for i = 0; i < unique.length(); i = i + 1 {
    for j = i; j < unique.length(); j = j + 1 {
      rows.push(license_pair_compatibility(unique[i], unique[j]))
    }
  }
  rows
}

///|
pub fn inventory_compatibility_matrix(
  inventory : Array[LicenseUse],
) -> Array[CompatibilityCell] {
  compatibility_matrix(inventory_licenses(inventory))
}

///|
pub fn compatibility_matrix_report(cells : Array[CompatibilityCell]) -> String {
  let rows : Array[String] = ["left,right,compatible,reason"]
  for cell in cells {
    rows.push(
      cell.left +
      "," +
      cell.right +
      "," +
      bool_word(cell.compatible) +
      "," +
      cell.reason,
    )
  }
  join_lines(rows)
}

///|
pub fn incompatible_pairs(
  cells : Array[CompatibilityCell],
) -> Array[CompatibilityCell] {
  let rows : Array[CompatibilityCell] = []
  for cell in cells {
    if !cell.compatible {
      rows.push(cell)
    }
  }
  rows
}

///|
pub fn compatibility_summary(cells : Array[CompatibilityCell]) -> String {
  let bad = incompatible_pairs(cells)
  if bad.is_empty() {
    "all checked license pairs are compatible in compact rules"
  } else {
    bad.length().to_string() + " license pair(s) need review"
  }
}