#!/usr/bin/env python3

## Find new available releases containing CVE fixes.
## Usage:
##     {0} user/projname "command returning the current version installed"

import os
import sys
import subprocess
import requests

try:
    from packaging.version import Version
except ImportError as e:
    print(
        "UNKNOWN - Missing dependency, please install package 'python3-packaging'.",
        file=sys.stderr,
    )
    sys.exit(3)

if os.environ["USER"] == "root":
    print("Must not be run as root", file=sys.stderr)
    sys.exit(3)

# very basic args parsing is good enough
gh_project = sys.argv[1]
cmd_getversion = sys.argv[2]

try:
    cmd = subprocess.run(cmd_getversion.split(), check=True, capture_output=True)
except Exception as e:
    print(
        f"UNKNOWN - Failed guess current running version of {gh_project} with command `{cmd_getversion}`.\n",
        file=sys.stderr,
    )
    print(e)
    sys.exit(3)
current_version = Version(cmd.stdout.decode().split("\n")[0].split(" ")[-1])

req = requests.get(f"https://api.github.com/repos/{gh_project}/releases", timeout=10)
if not req.ok:
    print(f"Couldn't get releases page for project {gh_project}", file=sys.stderr)
    sys.exit(3)

releases = [
    release for release in req.json() if not release["prerelease"]
]  # filter out nightly release

security_releases = set()
normal_releases = set()
for release in releases:
    if current_version < Version(release["tag_name"]):
        if release["body"] and (
            "CVE" in release["body"] or "vuln" in release["body"].lower()
        ):
            security_releases.add(release["tag_name"])
        else:
            normal_releases.add(release["tag_name"])
    if current_version == Version(release["tag_name"]):
        break
    if current_version > Version(release["tag_name"]):  # we should have breaked before
        print(
            f"UNKNOWN - {gh_project} current version ({current_version} > latest ({release['tag_name']}), something's wrong. Looks like version {current_version} does not exist anymore."
        )
        sys.exit(3)

if not security_releases:
    print(
        f"OK - No security releases found for {gh_project} (current running version {current_version})"
    )
    if len(normal_releases):
        print(
            "\nAvailable normal releases:\n  - "
            + "\n  - ".join(sorted(normal_releases))
        )
    sys.exit(0)

print(
    f"WARNING - Security fix available for {gh_project}.\n\nThe following releases provide security fixes, please consider upgrading ASAP:"
)
print("  - " + "\n  - ".join(sorted(security_releases)))
sys.exit(1)
