
# 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

import datetime
import time

from xossynchronizer.steps.syncstep import SyncStep
from xossynchronizer.modelaccessor import ProgranServiceInstance, ENodeB, Handover, ServiceInstanceLink, MCordSubscriberInstance

from xosconfig import Config
from multistructlog import create_logger
import requests
from requests.auth import HTTPBasicAuth



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 SyncProgranServiceInstanceBack(SyncStep):
    provides = [ProgranServiceInstance]

    observes = ProgranServiceInstance


    def call(self, failed=[], deletion=False):
        """
        Read profile from progran and save them in xos
        """

        if deletion == False:
            # NOTE we won't it to run only after the delete has completed
            return

        log.debug("Reading profiles from progran")
        onos = ProgranHelpers.get_progran_onos_info(self.model_accessor)
        profile_url = "http://%s:%s/onos/progran/profile/" % (onos['url'], onos['port'])
        r = requests.get(profile_url, auth=HTTPBasicAuth(onos['username'], onos['password']))
        res = r.json()['ProfileArray']


        # remove default profiles
        res = [p for p in res if "Default" not in p['Name']]
        pnames = [p['Name'] for p in res]
        log.debug("Received Profiles: ", profiles=pnames)

        field_mapping = {
            'Name': 'name',
            'Start': 'start',
            'End': 'end'
        }

        field_transformations = {
            'Start': ProgranHelpers.date_to_time,
            'End': ProgranHelpers.date_to_time
        }

        handover_mapping = {
            'A5Hysteresis': 'HysteresisA5',
            'A3Hysteresis': 'HysteresisA3'
        }

        updated_profiles = []

        for p in res:


            # checking for profiles
            try:
                si = ProgranServiceInstance.objects.get(name=p['Name'])
                log.debug("Profile %s already exists, updating it" % p['Name'])

            except IndexError:
                si = ProgranServiceInstance()

                si.created_by = "Progran"

                log.debug("Profile %s is new, creating it" % p['Name'])

            if not si.is_new:
                # update IMSI association
                xos_imsis_for_profile = [i.subscriber_service_instance.leaf_model for i in si.provided_links.all()]
                progran_imsis_for_profile = p['IMSIRuleArray']

                log.debug("List of imsis for profile %s in XOS" % p["Name"], imsis=xos_imsis_for_profile)
                log.debug("List of imsis for profile %s in ONOS" % p["Name"], imsis=progran_imsis_for_profile)

                for i in xos_imsis_for_profile:
                    if not i.imsi_number in progran_imsis_for_profile:
                        log.debug("Removing Imsi %s from profile %s" % (i.imsi_number, p['Name']))

                        imsi_link = ServiceInstanceLink.objects.get(subscriber_service_instance_id=i.id)

                        # NOTE: this model has already been removed from the backend, no need to synchronize
                        imsi_link.backend_need_delete = False
                        imsi_link.no_sync = True
                        imsi_link.save() # we need to save it to avoid a synchronization loop

                        imsi_link.delete()
                    else:
                        # remove from imsi list coming from progran everything we already know about
                        progran_imsis_for_profile.remove(i.imsi_number)

                for i in progran_imsis_for_profile:
                    log.debug("Adding Imsi %s to profile %s" % (i, p['Name']))
                    imsi = MCordSubscriberInstance.objects.get(imsi_number=i)
                    imsi_to_profile = ServiceInstanceLink(provider_service_instance=si,
                                                          subscriber_service_instance=imsi)
                    imsi_to_profile.save()

            # if the model has not been synchronized yet, skip it
            if not si.is_new and si.no_sync is False:
                log.debug("Skipping profile %s as not synchronized" % p['Name'])
                # NOTE add it to the removed profiles to avoid deletion (this is ugly, I know)
                updated_profiles.append(si.name)
                continue

            si = ProgranHelpers.update_fields(si, p, field_mapping, field_transformations)

            # checking for handovers
            handover_dict = p['Handover']
            handover_dict = ProgranHelpers.convert_keys(handover_dict, handover_mapping)
            del p['Handover']

            if si.handover_id:
                handover = si.handover
                log.debug("handover already exists, updating it", handover=handover_dict)
            else:
                handover = Handover()
                handover = ProgranHelpers.update_fields(handover, handover_dict)
                log.debug("handover is new, creating it", handover=handover_dict)
                handover.created_by = "Progran"

            handover = ProgranHelpers.update_fields(handover, handover_dict)
            handover.save()

            # Assigning handover to profile
            si.handover = handover

            si.backend_status = "OK"
            si.backend_code = 1

            si.no_sync = True
            si.previously_sync = True

            if p["MMECfg"]:
                si.mmeip = str(p["MMECfg"]["IPAddr"])
                si.mmeport = str(p["MMECfg"]["Port"])

            si.enacted = time.mktime(datetime.datetime.now().timetuple())

            si.save()

            updated_profiles.append(si.name)

        existing_profiles = [p.name for p in ProgranServiceInstance.objects.all() if not p.is_new]
        deleted_profiles = ProgranHelpers.list_diff(existing_profiles, updated_profiles)

        if len(deleted_profiles) > 0:
            for p in deleted_profiles:
                si = ProgranServiceInstance.objects.get(name=p)
                if si.created_by == 'XOS' and si.previously_sync == False:
                    # don't delete if the profile has been created by XOS and it hasn't been sync'ed yet
                    continue
                # TODO delete also the associated Handover
                log.debug("Profiles %s have been removed in progran, removing it from XOS" % str(p))
                si.delete()
