"""
SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
SPDX-License-Identifier: LicenseRef-ONF-Member-1.01
"""
import sys
import re
from datetime import datetime
import time

from flask import Flask, request
import logging as log
from argparse import ArgumentParser, SUPPRESS
import threading

from roc import Roc
from prom import Prometheus
from ping import ping
import device

app = Flask(__name__)

devices = {} # dict imsi:device
lock = threading.Lock()
probe_start = threading.Event()
probe_stop = threading.Event()


@app.route("/devices")
def get_devices():
    global devices, lock
    with lock:
        all = {}
        for _, device in devices.items():
            all[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
    return all

@app.route("/devices/reachable")
def get_devices_reachable():
    global devices, lock
    with lock:
        reachable = {}
        for _, device in devices.items():
            if device.reachable is True:
                reachable[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
    return reachable

@app.route("/devices/unreachable")
def get_devices_unreachable():
    global devices, lock
    with lock:
        unreachable = {}
        for _, device in devices.items():
            if device.reachable is False:
                unreachable[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
    return unreachable

@app.route("/probe")
def probe():
    update_and_probe()
    return get_devices_reachable()

@app.route("/config")
def config():
    global args, probe_stop
    period = request.args.get('period')
    if period is not None:
        period = int(period)
        if period == 0:
            log.info("Stopping probes...")
            args.period = period
            probe_stop.set()
        else:
            log.info("Starting probes...")
            args.period = period
            probe_start.set()
    config = vars(args)
    config.pop('token', None)
    config.pop('user', None)
    config.pop('password', None)
    return config


def build_argparser():
    parser = ArgumentParser(add_help=False)
    args = parser.add_argument_group('Options')
    args.add_argument('-h', '--help',
                      action='help',
                      default=SUPPRESS,
                      help='Show this help message and exit.')
    args.add_argument("--user",
                      help="ROC username",
                      type=str)
    args.add_argument("--password",
                      help="ROC password",
                      type=str)
    args.add_argument("--token",
                      help="Rancher bearer token",
                      type=str)
    args.add_argument("--port",
                      help="Service port",
                      type=str,
                      default="3333")
    args.add_argument("--period",
                      help="Probing period in sec",
                      type=int,
                      default=180)
    return parser

def update(roc, prom, old):
    new = roc.update_devices(old)
    if new is not None:
        new = prom.update_devices(new)
    else:
        new = old
    return new

def probe(devices):
    for imsi_id, device in devices.items():
        if device.ip is None:
            continue
        if ping(device.ip):
            device.reachable = True
            device.last_reachable = datetime.now()
            log.info("{}/{}/{} - reachable".format(device.imsi_id, device.imsi, device.ip))
        else:
            device.reachable = False
            log.info("{}/{}/{} - unreachable".format(device.imsi_id, device.imsi, device.ip))

def update_and_probe():
    global devices, lock
    new = update(roc, prom, devices)
    probe(new)
    with lock:
        devices = new

def work_thread(roc, prom):
    global args
    while True:
        probe_start.wait()
        probe_start.clear()
        log.info("Probing started")
        while True:
            update_and_probe()
            if probe_stop.wait(timeout=args.period):
                log.info("Probing stopped")
                probe_stop.clear()
                break

if __name__ == '__main__':

    log.basicConfig(
        format='%(asctime)s %(levelname)-8s %(message)s',
        level=log.DEBUG,
        datefmt='%Y-%m-%d %H:%M:%S',
        stream=sys.stdout)

    log.info("Starting network-diag-app...")

    args = build_argparser().parse_args()

    roc = Roc(args.user, args.password)
    prom = Prometheus(args.token.split(':')[0], args.token.split(':')[1])

    t = threading.Thread(target=work_thread, args=(roc, prom,))
    t.start()
    probe_start.set()

    app.run('0.0.0.0', args.port)
