"""
SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
SPDX-License-Identifier: LicenseRef-ONF-Member-1.01
"""

import requests
import json
# noinspection PyUnresolvedReferences
from requests.structures import CaseInsensitiveDict
import logging as log
import pyaml
from datetime import datetime

from device import Device

URL = "https://roc.menlo.aetherproject.org/aether-roc-api/aether/v4.0.0/connectivity-service-v4/"


# URL = "https://roc.staging.aether.onlab.us/aether-roc-api/aether/v4.0.0/connectivity-service-v4/"


class Roc(object):

    def __init__(self, user, password):
        self.user = user
        self.password = password
        self.key = self.get_key()

    def headers(self):
        h = CaseInsensitiveDict()
        h["Content-Type"] = "application/json"
        h["Authorization"] = "Bearer " + self.key
        return h

    def get_mbr(self, device_group):
        url = URL + "vcs/vcs/vcs-{}/slice/mbr".format(device_group)
        response = requests.get(url, headers=self.headers())
        if response.status_code != 200:
            log.error("Failed to get mbr, status_code: {}".format(response.status_code))
            return None
        mbr = json.loads(response.text)
        return mbr

    def set_mbr(self, device_group, mbr):
        log.info("Set {} mbr to {}".format(device_group, mbr))
        m = {'uplink': mbr}
        url = URL + "vcs/vcs/vcs-{}/slice/mbr".format(device_group)
        response = requests.post(url, headers=self.headers(), json=m)

        # If error, renew api key and try again
        if response.status_code != 201:
            log.info("Renew ROC api key")
            self.key = self.get_key()
            response = requests.post(url, headers=self.headers(), json=m)
            if response.status_code != 201:
                log.error("Failed to set mbr, device_group:{}, mbr:{}, status_code: {}".format(device_group, mbr,
                                                                                               response.status_code))
                # noinspection PyUnresolvedReferences
                sys.exit()

    def get_key(self):
        url = "https://keycloak.opennetworking.org/auth/realms/master/protocol/openid-connect/token"
        headers = CaseInsensitiveDict()
        headers["Content-Type"] = "application/x-www-form-urlencoded"
        data = {
            'grant_type': 'password',
            'client_id': 'aether-roc-gui',
            'username': self.user,
            'password': self.password,
            'scope': 'openid profile email groups'
        }
        response = requests.post(url, data, headers)
        key = json.loads(response.text)['access_token']
        return key

    def get_enterprise(self):
        url = URL + "enterprise"
        response = requests.get(url, headers=self.headers())
        if response.status_code != 200:
            log.error("get_enterprise() failed, status_code: {}".format(response.status_code))
            return None
        return json.loads(response.text)

    def get_site(self):
        url = URL + "site"
        response = requests.get(url, headers=self.headers())
        if response.status_code != 200:
            log.error("get_site() failed, status_code: {}".format(response.status_code))
            return None
        return json.loads(response.text)

    def get_upf(self):
        url = URL + "upf"
        response = requests.get(url, headers=self.headers())
        if response.status_code != 200:
            log.error("get_upf() failed, status_code: {}".format(response.status_code))
            return None
        return json.loads(response.text)

    def get_devicegroups(self):
        url = URL + "device-group"
        response = requests.get(url, headers=self.headers())
        if response.status_code != 200:
            log.error("get_devicegroups() failed, status_code: {}".format(response.status_code))
            return None
        return json.loads(response.text)['device-group']

    def get_ipdomain(self):
        url = URL + "ip-domain"
        response = requests.get(url, headers=self.headers())
        if response.status_code != 200:
            log.error("get_ipdomain() failed, status_code: {}".format(response.status_code))
            return None
        return json.loads(response.text)['ip-domain']

    def get_devices(self):
        devices = {}
        for dg in self.get_devicegroups():
            for d in dg['imsis']:
                devices[d['imsi-id']] = d['imsi-range-from']
        return devices

    def update_devices(self, devices):
        new = {}
        dgs = self.get_devicegroups()
        for dg in dgs:
            for d in dg['imsis']:
                imsi_id = str(d['imsi-id'])
                imsi = str(d['imsi-range-from'])
                last_reachable = datetime.min
                if imsi_id in devices:
                    last_reachable = devices[imsi_id].last_reachable
                new[imsi_id] = Device(imsi_id, imsi, last_reachable)
        return new

    def get_subnet(self):
        subnets = {}
        ip_domains = self.get_ipdomain()
        for ip_domain in ip_domains:
            subnets[ip_domain['id']] = ip_domain['subnet']
        return subnets


    def dump(self):
        print(pyaml.dump(self.get_enterprise()))
        print(pyaml.dump(self.get_site()))
        print(pyaml.dump(self.get_upf()))
        print(pyaml.dump(self.get_devicegroups()))
        print(pyaml.dump(self.get_ipdomain()))



if __name__ == '__main__':
    # use valid keycloak user/password
    roc = Roc("user", "password")

    print(pyaml.dump(roc.get_enterprise()))
    print(pyaml.dump(roc.get_site()))
    print(pyaml.dump(roc.get_upf()))
    print(pyaml.dump(roc.get_devicegroups()))
    print(pyaml.dump(roc.get_ipdomain()))

    cameras = "menlo-4g-cameras"

    mbr = roc.get_mbr(cameras)
    print("uplink mbr:{}, downlink mbr: {}".format(mbr["uplink"], mbr["downlink"]))
    roc.set_mbr(cameras, 5000000)
    mbr = roc.get_mbr(cameras)
    print("uplink mbr:{}, downlink mbr: {}".format(mbr["uplink"], mbr["downlink"]))
    roc.set_mbr(cameras, 10000000)
    mbr = roc.get_mbr(cameras)
    print("uplink mbr:{}, downlink mbr: {}".format(mbr["uplink"], mbr["downlink"]))
