
# 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 synchronizers.new_base.syncstep import SyncStep
from synchronizers.new_base.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()
        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.name))
                si.delete()
