#!/usr/bin/env python3
from __future__ import annotations

import os
import sys
import time
from pathlib import Path
from typing import Callable


def collect(
    root: Path = Path("/"),
    statvfs: Callable[[Path], os.statvfs_result] = os.statvfs,
) -> dict[str, float]:
    stat = statvfs(root)
    blocks = stat.f_blocks or 1
    files = stat.f_files or 1
    gib = 1024**3
    return {
        "used_pct": round((blocks - stat.f_bfree) * 100.0 / blocks, 2),
        "avail_gib": round(stat.f_bavail * stat.f_frsize / gib, 2),
        "reserved_gib": round((stat.f_bfree - stat.f_bavail) * stat.f_frsize / gib, 2),
        "inodes_pct": round((files - stat.f_ffree) * 100.0 / files, 2),
    }


def main() -> int:
    update = 30
    root = Path(os.environ.get("SM_DISK_PATH", "/"))
    print(
        "CHART system_monitor.disk_root '' 'Root disk guard' "
        f"'percent GiB' system_monitor disk_root line 60015 {update}"
    )
    for name in ("used_pct", "avail_gib", "reserved_gib", "inodes_pct"):
        print(f"DIMENSION {name} '{name}' absolute 1 1")
    while True:
        metrics = collect(root)
        print("BEGIN system_monitor.disk_root")
        for name, value in metrics.items():
            print(f"SET {name} = {value}")
        print("END")
        sys.stdout.flush()
        if os.environ.get("SM_ONESHOT"):
            return 0
        time.sleep(update)


if __name__ == "__main__":
    raise SystemExit(main())
