#!/usr/bin/env python3
#
# Compare two CVE reports and output a formatted rST CVE array (for release
# notes).
#
# We consider that a CVE is "fixed" if either:
# - the CVE status changes from Unpatched to Patched in the new report.
# - the Unpatched CVE is unlisted in the new report.
#
# Reports can be found here: https://valkyrie.yocto.io/pub/non-release/?type=metrics

import sys
import json

json_prev_path = sys.argv[1]
json_next_path = sys.argv[2]

data_prev, data_next = None, None

with open(json_prev_path, 'r') as fd_prev, open(json_prev_path, 'r') as fd_next:
    data_prev = json.load(fd_prev)["package"]
    data_next = json.load(fd_next)["package"]

patched_cves = {}

for pkg_prev in data_prev:
    pkg_name = pkg_prev["name"]

    pkg_next = None
    for p in data_next:
        if p["name"] == pkg_name:
            pkg_next = p
            break

    if pkg_next is not None:
        prev_unpatched = [cve["id"] for cve in pkg_prev["issue"] if cve["status"] == "Unpatched"]
        # next_patched = set([cve["id"] for cve in pkg_next["issue"] if cve["status"] == "Patched"])
        pkg_patched_cves = []
        for cve in prev_unpatched:
            if cve in pkg_next["issue"] and pkg_next["issue"][cve]["status"] == "Patched":
                pkg_patched_cves.append(cve)
            if cve not in pkg_next["issue"]:
                pkg_patched_cves.append(cve)

        if pkg_patched_cves:
            patched_cves[pkg_name] = sorted(pkg_patched_cves, key=lambda cve: (int(cve.split('-')[1]), int(cve.split('-')[2])))

if not patched_cves:
    print("No patched CVEs found")
    exit(0)

# Remove -native duplicates
for pkg in list(patched_cves):
    if pkg.endswith("-native") and pkg[:-len("-native")] in patched_cves:
        patched_cves.pop(pkg)

print(""".. list-table::
   :widths: 30 70
   :header-rows: 1

   * - Recipe
     - CVE IDs""")

for pkg in sorted(patched_cves.keys()):
    cves_rst = ", ".join([f":cve_nist:`{c[4:]}`" for c in patched_cves[pkg]])
    print(f"   * - ``{pkg}``")
    print(f"     - {cves_rst}")
