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

import os
import sys
import time
from pathlib import Path


def stale_junk_mb(root: Path, stale_hours: int, uid: int) -> int:
    cutoff = time.time() - stale_hours * 3600
    total = 0
    for dirpath, _dirnames, filenames in os.walk(root):
        for name in filenames:
            path = Path(dirpath) / name
            try:
                st = path.lstat()
            except OSError:
                continue
            if st.st_uid == uid and st.st_mtime <= cutoff:
                total += st.st_size
    return int(total / 1024 / 1024)


def collect(root: Path = Path("/tmp"), stale_hours: int = 72, uid: int = 1000) -> dict[str, float | int]:
    try:
        st = os.statvfs(root)
        blocks = st.f_blocks or 1
        files = st.f_files or 1
        used_pct = round((blocks - st.f_bfree) * 100.0 / blocks, 2)
        inodes_pct = round((files - st.f_ffree) * 100.0 / files, 2)
    except OSError:
        used_pct = 0.0
        inodes_pct = 0.0
    return {"used_pct": used_pct, "inodes_pct": inodes_pct, "stale_junk_mb": stale_junk_mb(root, stale_hours, uid)}


def main() -> int:
    update = 30
    root = Path(os.environ.get("SM_TMP_PATH", "/tmp"))
    stale_hours = int(os.environ.get("SM_TMP_STALE_HOURS", "72"))
    print(f"CHART system_monitor.tmpfs_tmp '' '/tmp tmpfs guard' 'percent percent MiB' system_monitor tmpfs_tmp line 60010 {update}")
    print("DIMENSION used_pct 'used_pct' absolute 1 1")
    print("DIMENSION inodes_pct 'inodes_pct' absolute 1 1")
    print("DIMENSION stale_junk_mb 'stale_junk_mb' absolute 1 1")
    while True:
        metrics = collect(root, stale_hours, 1000)
        print("BEGIN system_monitor.tmpfs_tmp")
        for key in ("used_pct", "inodes_pct", "stale_junk_mb"):
            print(f"SET {key} = {metrics[key]}")
        print("END")
        sys.stdout.flush()
        if os.environ.get("SM_ONESHOT"):
            return 0
        time.sleep(update)


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