#!/usr/bin/env python3
#
# Copyright © 2021 NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
#
# This software product is a proprietary product of Nvidia Corporation and its affiliates
# (the "Company") and all right, title, and interest in and to the software
# product, including all associated intellectual property rights, are and
# shall remain exclusively with the Company.
#
# This software product is governed by the End User License Agreement
# provided with the software product.

import os
import shutil
import subprocess
import sys

crashdir = "/var/crash"


def get_used_space(path: str) -> int:
    """
    path: File system path

    Return the space used on the file system containing %path, as a percent
    value.

    This implementation tries to be compatible with the similar check in
    cl-support.
    """
    retval = subprocess.run(
        ["df", "--output=pcent", path],
        capture_output=True,
        check=True,
    )
    lines = retval.stdout.splitlines()
    assert len(lines) == 2, lines
    return int(lines[1].strip(b" %"))


def main():
    if not os.path.isdir(crashdir):
        return

    kdumps = [d for d in os.scandir(crashdir) if d.is_dir()]
    kdumps.sort(key=lambda d: d.name)
    has_witness_file = lambda d: os.path.exists(
        os.path.join(d.path, "cl-support.%s" % (d.name,)))
    kdumps_new = [d for d in kdumps if not has_witness_file(d)]

    if kdumps_new:
        # 80 is the same number used in cl-support
        threshold = 80
        # 14 is the same number used in support_cleanup.py
        while len(kdumps) > 14 or get_used_space(crashdir) > threshold:
            # Minimum of 1 dump is the same as the logic in support_cleanup.py
            if len(kdumps) == 1:
                print(
                    "Warning: will not delete last kdump to free space. Please free at least %d%% disk space manually or transfer %s to another system."
                    % (100 - threshold, kdumps[0].path),
                    file=sys.stderr)
                # stdout & stderr are flushed so that the output interleaves
                # sequentially in the systemd journal.
                sys.stderr.flush()
                break
            d = kdumps.pop(0)
            shutil.rmtree(d.path)
            if d in kdumps_new:
                kdumps_new.remove(d)
                comment = "new "
            else:
                comment = ""
            print("Deleted %skdump dir %s" % (comment, d.path))
            sys.stdout.flush()

        assert kdumps_new, kdumps

        msg = "found new kdump dir(s): %s" % (
            " ".join([d.name for d in kdumps_new]),)
        print(msg)
        sys.stdout.flush()
        retval = subprocess.run(["/usr/cumulus/bin/cl-support", "-r", msg])
        if retval.returncode != 0:
            print(
                "Error: cl-support exited with status %d" %
                (retval.returncode,),
                file=sys.stderr)
            sys.exit(1)


if __name__ == "__main__":
    main()
