"""
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
from flask_restful import Resource, Api
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__)
api = Api(app)

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


class Devices(Resource):
    def get(self):
        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

class ReachableDevices(Resource):
    def get(self):
        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

class UnreachableDevices(Resource):
    def get(self):
        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



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")
    return parser

def update(roc, prom, old):
    new = roc.update_devices(old)
    prom.update_devices(new)
    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 work_thread(roc, prom):
    global devices, lock
    while True:
        new = update(roc, prom, devices)
        probe(new)
        with lock:
            devices = new

        time.sleep(5)

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)

    api.add_resource(Devices, '/devices')
    api.add_resource(ReachableDevices, '/devices/reachable')
    api.add_resource(UnreachableDevices, '/devices/unreachable')

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

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