#
# This computer program is the confidential information and proprietary trade
# secret of Anuta Networks, Inc. Possessions and use of this program must
# conform strictly to the license agreement between the user and
# Anuta Networks, Inc., and receipt or possession does not convey any rights
# to divulge, reproduce, or allow others to use this program without specific
# written authorization of Anuta Networks, Inc.
#
# Copyright (c) 2015-2016 Anuta Networks, Inc. All Rights Reserved.
#

#
#DO NOT EDIT THIS FILE ITS AUTOGENERATED ONE
#ALL THE CUSTOMIZATIONS REGARDING DATAPROCESSING SHOULD BE WRITTEN INTO service_customization.py FILE
#
"""
Tree Structure of Handled XPATH:

services
        |
        day1services
                    |
                    day1service
                               |
                               tacacs
                                     
Schema Representation:

/services/day1services/day1service/tacacs
"""

from servicemodel import util
from servicemodel import yang
from servicemodel import devicemgr

from tclday0config.tclday0config_lib import getLocalObject
from tclday0config.tclday0config_lib import getDeviceObject
from tclday0config.tclday0config_lib import getCurrentObjectConfig
from tclday0config.tclday0config_lib import ServiceModelContext
from tclday0config.tclday0config_lib import getParentObject
from tclday0config.tclday0config_lib import log

#from servicemodel.controller import devices
from servicemodel.controller.devices.device import tacacs_conf,routes
import service_customization


class Tacacs(yang.AbstractYangServiceHandler):
    _instance = None

    def __init__(self):
        self.delete_pre_processor = service_customization.DeletePreProcessor()
        self.create_pre_processor = service_customization.CreatePreProcessor()
        self.opaque_args = {}

    def create(self, id, sdata):
        sdata.getSession().addYangSessionPreReserveProcessor(self.create_pre_processor)

        #Fetch Local Config Object
        config = getCurrentObjectConfig(id, sdata, 'tacacs')

        #Fetch Service Model Context Object
        smodelctx = None

        #Fetch Parent Object
        parentobj = None

        dev = []
        inputkeydict = {}
        devbindobjs={}
        inputdict = {}
        opaque_args = self.opaque_args

        # START OF FETCHING THE LEAF PARAMETERS
        inputdict['tacacs_server_group'] = config.get_field_value('tacacs_server_group')
        inputdict['timeout'] = config.get_field_value('timeout')
        inputdict['delete_dummy_tacacs_route'] = config.get_field_value('delete_dummy_tacacs_route')
        # END OF FETCHING THE LEAF PARAMETERS

        _Gen_obj = getLocalObject(sdata, 'day1service')
        device_mgmt_ip_address = _Gen_obj.day1service.device_ip

        #Fetch Device Object
        dev = getDeviceObject(device_mgmt_ip_address, sdata)

        # START OF FETCHING THE PARENT KEY LEAF PARAMETERS
        inputkeydict['day1services_day1service_device_ip'] = sdata.getRcPath().split('/')[-2].split('=')[1]
        # END OF FETCHING THE PARENT KEY LEAF PARAMETERS

        #Use the custom methods to process the data
        service_customization.ServiceDataCustomization.process_service_create_data(smodelctx, sdata, dev, id=id, device=dev, parentobj=parentobj, inputdict=inputdict, inputkeydict=inputkeydict, config=config, hopaque=opaque_args)

        #Start of Device binding with python bindings
        '''
        aaa_group_authentication_object = aaa_group.authentication.authentication()
        aaa_group_authentication_object.server_group = inputdict.get('tacacs_server_group')
        aaa_group_authentication_object_payload = aaa_group_authentication_object.getxml(filter=True)
       
        aaa_group_authorization_object = aaa_group.authorization.authorization()
        aaa_group_authorization_object.server_group = inputdict.get('tacacs_server_group')
        aaa_group_authorization_object_payload = aaa_group_authorization_object.getxml(filter=True)
        
        aaa_group_accounting_object = aaa_group.accounting.accounting()
        aaa_group_accounting_object.server_group = inputdict.get('tacacs_server_group')
        aaa_group_accounting_object_payload = aaa_group_accounting_object.getxml(filter=True)
       
            
        if util.isNotEmpty(inputdict.get('tacacs_server_group')):
            for dev_iterator in dev:
                yang.Sdk.createData(dev_iterator.url+'/basicDeviceConfigs:aaa-group', aaa_group_authentication_object_payload, sdata.getSession(), True)

                yang.Sdk.createData(dev_iterator.url+'/basicDeviceConfigs:aaa-group', aaa_group_authorization_object_payload, sdata.getSession(), True)

                yang.Sdk.createData(dev_iterator.url+'/basicDeviceConfigs:aaa-group', aaa_group_accounting_object_payload, sdata.getSession(), True)

        '''
        #tacacs_conf_object = devices.device.tacacs_conf.tacacs_conf()
        tacacs_conf_object = tacacs_conf.tacacs_conf()
        tacacs_conf_object.timeout = inputdict.get('timeout')
        tacacs_conf_object.tacacs_server_group = inputdict.get('tacacs_server_group')

        #dummy_route_object = devices.device.routes.route.route()
        dummy_route_object = routes.route.route()
        dummy_route_object.dest_ip_address = inputdict.get('delete_dummy_tacacs_route')
        dummy_route_object.dest_mask = '255.255.255.252'
        

        #End of Device binding
        devbindobjs['tacacs_conf_object'] = tacacs_conf_object
        #Use the custom method to process/create payload
        service_customization.ServiceDataCustomization.process_service_device_bindings(smodelctx, sdata, dev, id=id, device=dev, inputdict=inputdict, inputkeydict=inputkeydict, parentobj=parentobj, config=config, devbindobjs=devbindobjs, hopaque=opaque_args)

        tacacs_conf_object_payload = tacacs_conf_object.getxml(filter=True)

        log('tacacs_conf_object_payload: %s' % (tacacs_conf_object_payload))
        for dev_iterator in dev:
          yang.Sdk.createData(dev_iterator.url+'',tacacs_conf_object_payload, sdata.getSession(), True)

        for dev_iterator in dev:
            if inputdict['delete_dummy_tacacs_route'] is not None:
                static_route_url = dev_iterator.url + '/l3features:routes/route=%s,%s' % (dummy_route_object.dest_ip_address, dummy_route_object.dest_mask)
                output = yang.Sdk.invokeRpc('ncxsdk:get-inbound-references', '<input><rc-path>'+static_route_url+'</rc-path></input>')
                ref = util.parseXmlString(output)
                if hasattr(ref.output, 'references'):
                    if hasattr(ref.output.references, 'reference'):
                        for eachreference in util.convert_to_list(ref.output.references.reference):
                            if hasattr(eachreference, 'src_node'):
                                for each_ref in util.convert_to_list(eachreference.src_node):
                                    yang.Sdk.removeReference(each_ref, eachreference.dest_node)
                yang.Sdk.deleteData(static_route_url, '', sdata.getTaskId(), sdata.getSession())

        """
        for dev_iterator in dev:
                cred_set_payload = '<device><id>'+ str(device_mgmt_ip_address) +'</id><credential-set>creds_snmpv3</credential-set></device>'
                yang.Sdk.patchData(dev_iterator.url, cred_set_payload, sdata, add_reference=False)
        """

    def update(self, id, sdata):
        #Fetch Local Config Object
        config = getCurrentObjectConfig(id, sdata, 'tacacs')
        opaque_args = self.opaque_args

        #Fetch Service Model Context Object
        smodelctx = None

        #Fetch Parent Object
        parentobj = None

        dev = []
        inputkeydict = {}
        devbindobjs={}
        inputdict = {}
        opaque_args = self.opaque_args

        # START OF FETCHING THE LEAF PARAMETERS
        inputdict['tacacs_server_group'] = config.get_field_value('tacacs_server_group')
        inputdict['timeout'] = config.get_field_value('timeout')
        inputdict['delete_dummy_tacacs_route'] = config.get_field_value('delete_dummy_tacacs_route')
        # END OF FETCHING THE LEAF PARAMETERS

        _Gen_obj = getLocalObject(sdata, 'day1service')
        device_mgmt_ip_address = _Gen_obj.day1service.device_ip

        #Fetch Device Object
        dev = getDeviceObject(device_mgmt_ip_address, sdata)

        #Use the custom method to process the data
        service_customization.ServiceDataCustomization.process_service_update_data(smodelctx, sdata, id=id, dev=dev, parentobj=parentobj, config=config, hopaque=opaque_args, inputdict=inputdict)

    def delete(self, id, sdata):
        sdata.getSession().addYangSessionPreReserveProcessor(self.delete_pre_processor)

        #Fetch Local Config Object
        config = getCurrentObjectConfig(id, sdata, 'tacacs')
        opaque_args = self.opaque_args

        #Fetch Service Model Context Object
        smodelctx = None

        #Fetch Parent Object
        parentobj = None

        dev = []
        inputkeydict = {}
        devbindobjs={}
        inputdict = {}
        opaque_args = self.opaque_args

        # START OF FETCHING THE LEAF PARAMETERS
        inputdict['tacacs_server_group'] = config.get_field_value('tacacs_server_group')
        inputdict['timeout'] = config.get_field_value('timeout')
        inputdict['delete_dummy_tacacs_route'] = config.get_field_value('delete_dummy_tacacs_route')
        # END OF FETCHING THE LEAF PARAMETERS

        _Gen_obj = getLocalObject(sdata, 'day1service')
        device_mgmt_ip_address = _Gen_obj.day1service.device_ip

        #Fetch Device Object
        dev = getDeviceObject(device_mgmt_ip_address, sdata)

       

        #Use the custom method to process the data
        service_customization.ServiceDataCustomization.process_service_delete_data(smodelctx, sdata, id=id, dev=dev, parentobj=parentobj, config=config, hopaque=opaque_args, inputdict=inputdict)

        #TO TEST Side Effects of rolling back to dummy static route
        """
        dummy_route_object = devices.device.routes.route.route()
        dummy_route_object.dest_ip_address = inputdict.get('delete_dummy_tacacs_route')
        dummy_route_object.dest_mask = '255.255.255.252'
        dummy_route_object.interface_name = 'Null0'
        dummy_route_object.id = 'ip route ' + dummy_route_object.dest_ip_address + ' ' + dummy_route_object.dest_mask + ' ' + dummy_route_object.interface_name

        for dev_iterator in dev:
            if inputdict['delete_dummy_tacacs_route'] is not None:
                static_route_url = dev_iterator.url + '/l3features:routes/route=%s,%s' % (dummy_route_object.dest_ip_address, dummy_route_object.dest_mask)
                yang.Sdk.createData(static_route_url, dummy_route_object.getxml(filter=True), sdata.getSession())
        """
    @staticmethod
    def getInstance():
        if(Tacacs._instance == None):
            Tacacs._instance = Tacacs()
        return Tacacs._instance

    def rollbackCreate(self, id, sdata):
        log('rollback: id = %s, sdata = %s' % (id, sdata))
        self.delete(id,sdata)

if __name__ == 'tacacs':
  from servicemodel.yang import YangServiceData
  sdata = YangServiceData()
  instance = Tacacs().getInstance()
  instance.create(None, sdata)
  instance.delete(None, sdata)
  instance.update(None, sdata)
