
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import os
import sys
from xossynchronizer.steps.syncstep import SyncStep
from xossynchronizer.modelaccessor import ProgranServiceInstance, ENodeB, Handover

from xosconfig import Config
from multistructlog import create_logger
import json
import requests
from requests.auth import HTTPBasicAuth
import time
import datetime


log = create_logger(Config().get('logging'))

parentdir = os.path.join(os.path.dirname(__file__), "..")
sys.path.insert(0, parentdir)
sys.path.insert(0, os.path.dirname(__file__))
from helpers import ProgranHelpers

class SyncProgranServiceInstance(SyncStep):
    provides = [ProgranServiceInstance]

    observes = ProgranServiceInstance

    def sync_record(self, o):
        onos = ProgranHelpers.get_progran_onos_info(self.model_accessor)

        log.info("sync'ing profile", object=str(o), **o.tologdict())

        profile_url = "http://%s:%s/onos/progran/profile/" % (onos['url'], onos['port'])
        data = self.get_progran_profile_field(o)
        log.debug("Sync'ing profile with data", request_data=data)

        if o.previously_sync == False:
            log.debug("Sending POST", url=profile_url, data=json.dumps(data))
            r = requests.post(profile_url, data=json.dumps(data), auth=HTTPBasicAuth(onos['username'], onos['password']))
        else:
            log.debug("Sending PUT", url=profile_url, data=json.dumps(data))
            r = requests.put(profile_url, data=json.dumps(data),
                              auth=HTTPBasicAuth(onos['username'], onos['password']))

        ProgranHelpers.get_progran_rest_errors(r)
        log.info("Profile synchronized", response=r.json())

        if o.enodeb_id:
            log.info("adding profile %s to enodeb %s" % (o.id, o.enodeb.enbId), object=str(o), **o.tologdict())
            enodeb_url = "http://%s:%s/onos/progran/enodeb/%s/profile" % (onos['url'], onos['port'], o.enodeb.enbId)
            data = {
                "ProfileArray": [
                    o.name
                ]
            }
            log.debug("Adding enodeb to profile with data", request_data=data)
            r = requests.post(enodeb_url, data=json.dumps(data), auth=HTTPBasicAuth(onos['username'], onos['password']))
            ProgranHelpers.get_progran_rest_errors(r)
            o.active_enodeb_id = o.enodeb_id # storing the value to know when it will be deleted
            log.info("EnodeB synchronized", response=r.json())
        elif o.active_enodeb_id:
            enb_id = ENodeB.objects.get(id=o.active_enodeb_id).enbId
            log.info("removing profile %s from enodeb %s" % (o.name, o.active_enodeb_id), object=str(o), **o.tologdict())
            enodeb_url = "http://%s:%s/onos/progran/enodeb/%s/profile/%s" % (onos['url'], onos['port'], enb_id, o.name)
            r = requests.delete(enodeb_url, auth=HTTPBasicAuth(onos['username'], onos['password']))
            ProgranHelpers.get_progran_rest_errors(r)
            o.active_enodeb_id = 0 # removing the value because it has been deleted
            log.info("EnodeB synchronized", response=r.json())

        o.previously_sync = True
        o.no_sync = True
        o.save()

    def get_handover_for_profile(self, o):
        return {
            "A3Hysteresis": o.handover.HysteresisA3,
            "A3TriggerQuantity": o.handover.A3TriggerQuantity,
            "A3offset": o.handover.A3offset,
            "A5Hysteresis": o.handover.HysteresisA5,
            "A5Thresh1Rsrp": o.handover.A5Thresh1Rsrp,
            "A5Thresh1Rsrq": o.handover.A5Thresh1Rsrq,
            "A5Thresh2Rsrp": o.handover.A5Thresh2Rsrp,
            "A5Thresh2Rsrq": o.handover.A5Thresh2Rsrq,
            "A5TriggerQuantity": o.handover.A5TriggerQuantity,
        }

    def get_progran_profile_field(self, o):

        # basic information that we have in the service instance itself
        profile = {
            'AdmControl': o.AdmControl,
            "DlSchedType": o.DlSchedType,
            "Start": o.start, # TODO date has to be in the format dd.MM.yyyy HH:mm
            "UlSchedType": o.UlSchedType,
            "End": o.end, # TODO date has to be in the format dd.MM.yyyy HH:mm
            "CellIndividualOffset": o.CellIndividualOffset,
            "DlAllocRBRate": o.DlAllocRBRate,
            "Name": o.name,
            "UlAllocRBRate": o.UlAllocRBRate,
            "Handover": self.get_handover_for_profile(o),
            "MMECfg": {
                "Port": o.mmeport,
                "IPAddr": o.mmeip,
            },
            'DlWifiRate': o.DlWifiRate,
            'DlUeAllocRbRate': o.DlUeAllocRbRate,
        }

        return profile

    def delete_record(self, o):
        log.info("deleting profile", object=str(o), **o.tologdict())
        onos = ProgranHelpers.get_onos_info_from_si(o)
        profile_url = "http://%s:%s/onos/progran/profile/%s" % (onos['url'], onos['port'], o.name)
        r = requests.delete(profile_url, auth=HTTPBasicAuth(onos['username'], onos['password']))
        o.active_enodeb_id = 0  # removing the value because it has been deleted
        log.info("Profile synchronized", response=r.json())

    def fetch_pending(self, deleted):
        return super(SyncProgranServiceInstance, self).fetch_pending(deleted)
