#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
""" 
A script that checks available service and see if the are running 
"""
import re
import os, sys, json
import subprocess


def run_command(command, shell=False):
    """
    Run command "command".

    :param command: The command to run. Should be a list of strings, containing the program and its argument.
    :return: Tuple containing program output and return status code.
    """
    assert isinstance(command, list)
    p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stout, _ = p.communicate()

    if isinstance(stout, bytes):
        stout = stout.decode(errors='ignore') # Python 3

    return stout, p.returncode

def PsmClient(args):
    args.insert(0, '/usr/local/bluecat/PsmClient')
    out, _ = run_command(args)
    if out.find('retcode=ok') < 0:
        error_str = 'command: "PsmClient ' + ' '.join(args[1:]) + '" returned the following error: ' + out.rstrip()
        raise Exception(error_str)
    return out

known_services = {
      'dhcp-enable' : 'dhcp'
    , 'dns-enable' : 'dns'
    , 'firewall-enable' : 'firewall'
    , 'ssh-enable' : 'ssh'
}
inv_known_services = {v: k for k, v in known_services.items()}

service_to_remote_name = {
    'dns' : 'mmremote',
    'dhcp' : 'mmdhcpremote'
}


def update_service_state_in_psm(service_name, state):
    PsmClient(['node', 'set', inv_known_services[service_name] + '=' + state])

def getServices() -> dict:
    regexp = re.compile(r'^node \S+ (\S+)=(\d+)\s*$')
    services = {}
    out = PsmClient(['node', 'get'])
    for line in str(out).split(os.linesep):
        re_res = regexp.split(line)
        if len(re_res) > 3:
            if re_res[1] in known_services and re_res[1]:
                services[known_services[re_res[1]]] = re_res[2]
    return services

def setServices(services) -> dict:
    services_before = getServices()
    for service_name, value in services.items():
        if service_name in services_before and value != services_before.get(service_name):
            update_service_state_in_psm(service_name, value)
            #update_firewall()  open/close firewall is possible (or easy)

    services_after = getServices()
    with open("/var/mmsuite/updater/services.conf", "w") as service_file:
        service_file.write(json.dumps(services_after))
    return services_after



if __name__ == '__main__':
    try:
        result = {}
        if (len(sys.argv) > 1) and (sys.argv[1] == '-set'):
            # input can either be an argument or a through stdin
            text = sys.argv[2] if len(sys.argv) > 2 else sys.stdin.read()
            input = json.loads(text)
            result = setServices(input)
        else:
            # assume this is get
            result = getServices()
        print(json.dumps(result))
    except Exception as e:
        sys.stderr.write(str(e) + "\n")
        sys.exit(1)


