#!/usr/bin/env python3

"""
<sphinx>
free-ram
--------

Monitors RAM memory usage to notify that a maximum percent of memory was used.

Parameters:

- max_ram_percentage (in percents eg. 80)
</sphinx>
"""

import re
from os import environ
from sys import stderr

if 'MAX_RAM_PERCENTAGE' not in environ:
    print("Missing MAX_RAM_PERCENTAGE parameter.\nUsage ./free_ram.py.", file=stderr)
    exit(127)


def check_ram(max_percent: float, meminfo_path: str = '/proc/meminfo') -> int:
    meminfo = open(meminfo_path).read()
    mem_total_reg = re.compile("MemTotal:\s+(\d+)")
    mem_avail_reg = re.compile("MemAvailable:\s+(\d+)")
    mem_total = float( mem_total_reg.split(meminfo)[1])
    mem_avail = float( mem_avail_reg.split(meminfo)[1])

    if "MOCK_FREE_RAM" in environ and "MOCK_TOTAL_RAM" in environ:
        mem_avail = float(environ["MOCK_FREE_RAM"]) * 1024
        mem_total = float(environ["MOCK_TOTAL_RAM"]) * 1024

    mem_used = mem_total - mem_avail
    mem_used_percent = mem_used/mem_total * 100

    if mem_used/mem_total * 100 > max_percent:
        print(
            ("RAM usage too high: {0:.0f}MiB/{1:.0f}MiB ({2:.0f}% used, {3:.0f}MiB left. Max usage allowed: {4:.0f}% ("
             + "{5:.0f}MiB) ")
            .format(
                mem_used / 1024,
                mem_total / 1024,
                mem_used_percent,
                mem_avail / 1024,
                max_percent,
                max_percent / 100.0 * mem_total / 1024
            )
        )
        return 1

    print(
        "RAM usage OK: {0:.0f}MiB/{1:.0f}MiB ({2:.0f}% used, {3:.0f}MiB left. Max usage allowed: {4:.0f}% ({5:.0f}MiB)"
        .format(
            mem_used / 1024, mem_total / 1024,
            mem_used_percent,
            mem_avail / 1024,
            max_percent,
            max_percent / 100.0 * mem_total / 1024
          )
    )
    return 0


exit(check_ram(float(environ["MAX_RAM_PERCENTAGE"])))
