#!/usr/bin/env python3

import docker
from pprint import pprint
import os
import requests
import sys
import signal
import time
import threading

# thread safe print
from tsprint import print



services = dict()
# Service               check url                                   initial delay, delay, dockername
services["analysis"]  = ["http://analysis:8081/health",                       30,  15,    "analysis"]
services["camunda"]   = ["http://camunda:8085/engine-rest/process-instance/", 300, 15,    "camunda"]
services["reporting"] = ["http://reporting:8083/health",                      30,  15,    "reporting"]
services["twitter"]   = ["http://twitter:8084/actuator/health",               60,  15,    "twitter"]
services["website"]   = ["http://website:8080/",                              30,  15,    "website"]



docker_ctl = None

def check_service(servicename):
    global services
#    print(servicename+" -- checking service.")
    try:
        r = requests.get(services[servicename][0], timeout=3)
        if r.status_code != 200:
            raise Exception("errorcode != 200: "+int(r.status_code))

        print("+ "+servicename+" -- looks good :)")

        # schedule next check
        th = threading.Timer(services[servicename][2], check_service, args=[servicename])
        th.setName('failover_'+servicename)
        th.start()
    except:
        print("- "+servicename+" -- looks bad :( "+str(sys.exc_info()[0]))
        reset_service(servicename)

        # schedule next check using startup delay
        th = threading.Timer(services[servicename][1], check_service, args=[servicename])
        th.setName('failover_'+servicename)
        th.start()



def reset_service(servicename):
    global services
    global docker_ctl
    print("  "+servicename+" -- restarting service")
    try:
        docker_ctl.containers.client.api.restart(services[servicename][3], timeout=1)
    except:
        print("! Docker said NO/service restart failed."+str(sys.exc_info()[0]))



if __name__ == "__main__":
    def signal_handler(signal, frame):
        print('SIG received. exitting!')
        os._exit(1)
    signal.signal(signal.SIGINT, signal_handler)

    docker_ctl = docker.from_env()
    print(docker_ctl.info())

    print()
    print("####################")
    print("# Failover service #")
    print("####################")

    pprint(services)
    print()

    print("Starting watchers")

    for servicename, service in services.items():
        th = threading.Timer(service[1], check_service, args=[servicename])
        th.setName('failover_'+servicename)
        th.start()
