"""
SPDX-FileCopyrightText: 2022-present Intel Corporation
SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
SPDX-License-Identifier: Apache-2.0
"""
import sys
import os
from datetime import datetime

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

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()


# curl http://localhost:3333/config?period=0
@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)
    args.add_argument("--url",
                      help="ROC url",
                      type=str,
                      default="https://roc.menlo.aetherproject.org/aether-roc-api/aether/v2.0.0/connectivity-service-v2/")
    args.add_argument("--enterprise",
                      help="Enterprise Id",
                      type=str,
                      default="aether-onf")
    args.add_argument("--site",
                      help="Site Id",
                      type=str,
                      default="menlo-4g")
    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 do_probe(devices):
    for _, 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)
    do_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()

    if not args.user:
        args.user = os.environ.get('ROCUSER')
    if not args.password:
        args.password = os.environ.get('ROCPASSWORD')
    if not args.token:
        args.token= os.environ.get('KEYCLOAKTOKEN')

    roc = Roc(args.url, args.user, args.password, args.enterprise, args.site)
    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)
