import psutil
import requests
from datetime import datetime
from pathlib import Path
import config


def get_service(name):
    service = None
    try:
        service = psutil.win_service_get(name)
        service = service.as_dict()
        if service['pid']:
            service['process'] = psutil.Process(service['pid']).as_dict()
        else:
            service['process'] = ''
    except Exception as ex:
        print(str(ex))
    return service


def process_info(program_path):
    offset = len(program_path) + 1
    info = []
    for p in psutil.process_iter():
        try:
            if p.exe().startswith(program_path):
                info.append({
                    'path': p.exe()[offset:],
                    'memory': str(p.memory_info().rss // 1048576),
                    'cpu': str(p.cpu_percent())
                })
        except psutil.AccessDenied:
            pass
    return sorted(info, key=lambda x: x['path'])


def service_status(name, stats=False):
    service = get_service(name)

    if not service:
        print(f"Dienst '{name}' nicht vorhanden !!")
        return

    print(f"Dienst {service['display_name']} ({name})... ", end='')
    if service['status'] != 'running':
        print('inaktiv!')
        print(f"!! Fehler: Status {service['status']} !!")
        return

    print("läuft.")
    delta = (datetime.now() - datetime.fromtimestamp(service['process']['create_time'])).total_seconds()
    uptime = "{0:n} Tage, {1:n} Stunden, {2:n} Minuten".format(
             delta // 86400, (delta % 86400) // 3600, ((delta % 86400) % 3600) // 60)
    print(f"   Pfad:      {service['process']['exe']} ")
    print(f"   Laufzeit:  {uptime} ")
    # print(f"   Speichernutzung: {service['process']['memory_info'].rss//1048576}")

    if not stats:
        return

    program_path = str(Path(service['process']['exe']).parent.parent)
    print('')
    print('   Prozess                           RAM       CPU')
    for info in process_info(program_path):
        print('    ' + info['path'].ljust(32) + (info['memory'] + ' MB').rjust(8) + (info['cpu'] + ' %').rjust(9))


def webservice_status(site):
    print(f"Cognos-Webservice {site}... ", end='')
    try:
        res = requests.get(site)
        if res.status_code not in [200, 441]:
            print(res.status_code)
            if b'DPR-ERR-2109' in res.content:
                print('!! Fehler: Dienst wird noch gestartet, Dispatcher ist nicht erreichbar !!')
        else:
            print('online.')
            if site.endswith('health'):
                print(res.json())
    except requests.ConnectionError:
        print('OFFLINE !!')
        print('!! Fehler: Dienst ist nicht erreichbar !!')
        return


def cognos11_services():
    service_status('apacheds-cognos')
    service_status('MsgServ')
    service_status('ol_cognoscm')
    service_status('IBM Cognos', stats=True)
    cfg = config.Config()
    webservice_status(cfg.cognos_url)
    webservice_status(cfg.cognos_url + 'health')


if __name__ == '__main__':
    cognos11_services()