#!/usr/bin/python
import os, sys, getopt
from dbus import SystemBus, SessionBus, Interface

def stop():
    print("Usage: %s [-s service] [-d device] [-m mount] [-f file]" % sys.argv[0])
    print("\n\t-f: read items from file")
    print("\t\tfile is a plain list of systemd units, with extensions")
    sys.exit(2)

# Parse options
try:
    myopts, args = getopt.gnu_getopt(sys.argv[1:],"s:d:m:f:")
except getopt.GetoptError as e:
    print (str(e))
    stop()

if len(myopts) == 0:
    stop()

# Create array of wanted systemd things
wanted = []
for o, a in myopts:
    if o == '-f':
        # Read wanted items from file
        try:
            with open(a, 'r') as fh:
                for item in fh.read().splitlines():
                    item = item.strip()       # no whitespace
                    item = item.split('#')[0] # Clear comments
                    if item != '' and item not in wanted:
                        wanted.append(item)
        except IOError:
            print("Can't open file '%s'!\n" % a)
            stop()
    else:
        if o == '-s' and not a.endswith('.service'): a = a + '.service'
        if o == '-d' and not a.endswith('.device'):  a = a + '.device'
        if o == '-m' and not a.endswith('.mount'):   a = a + '.mount'
        if a not in wanted: wanted.append(a)

# Get systemd units
bus     = SystemBus()
systemd = bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1')
systemd = Interface(systemd, dbus_interface='org.freedesktop.systemd1.Manager')
units   = systemd.ListUnits()

# Check wanted items against systemd units
found   = 0
checked = []
broken  = []
missing = []

for item in wanted:
    foundUnit = 0
    for unit in units:
        unit_name     = unit[0]
        description   = unit[1]
        unit_loaded   = unit[2]
        unit_status   = unit[3]
        script_status = unit[4]
        dbus_path     = unit[6]

        if (unit_name == item):
            foundUnit = 1
            found += 1

            if (unit_loaded == 'loaded' and unit_status == 'active' and (script_status == 'running' or script_status == 'mounted')):
                checked.append(item)
            else:
                broken.append("Service %s has state: %s %s %s" % (unit_name, unit_loaded, unit_status, script_status))

    if foundUnit == 0:
        missing.append(item)

# Complain about it
if found == 0:
    print("WARNING - Service %s not found by systemd, check the name or configuration" % ", ".join(wanted))
    sys.exit(1)
elif found != len(wanted):
    print("WARNING - Some service(s) were not found, others were. Check the names or configuration for %s" % ", ".join(missing))
    sys.exit(1)
else:
    if broken:
        print ("CRITICAL - %s" % ", ".join(broken))
        sys.exit(2)
    else:
        print ("OK - Services checked: %s" % ", ".join(checked))
        sys.exit(0)
