
# 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.


#
# Copyright 2016-present Ciena Corporation
#
# 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 json
##load the olt config

class OltConfig:
    def __init__(self, olt_conf_file = ''):
        if not olt_conf_file:
            self.olt_conf_file = os.getenv('OLT_CONFIG')
        else:
            self.olt_conf_file = olt_conf_file
        try:
            self.olt_handle = open(self.olt_conf_file, 'r')
            self.olt_conf = json.load(self.olt_handle)
            self.olt_conf['olt'] = True
        except:
            self.olt_handle = None
            self.olt_conf = {}
            self.olt_conf['olt'] = False

    def on_olt(self):
        return self.olt_conf['olt'] is True

    def olt_port_map(self):
        if self.on_olt() and self.olt_conf.has_key('port_map'):
            port_map = {}
            port_map['ponsim'] = self.olt_conf['port_map'].has_key('ponsim')
            if self.olt_conf['port_map'].has_key('switches'):
                port_map['switches'] = self.olt_conf['port_map']['switches']
            else:
                port_map['switches'] = []
                nr_switches = 1
                if self.olt_conf['port_map'].has_key('nr_switches'):
                    nr_switches = int(self.olt_conf['port_map']['nr_switches'])
                for sw in xrange(nr_switches):
                    switch = 'br-int{}'.format(sw+1) if sw > 0 else 'br-int'
                    port_map['switches'].append(switch)
            #if we have a host interface enabled, invalidate the switches config
            if self.olt_conf['port_map'].has_key('host'):
                #if host interface is specified, then use the host instead of ovs switch
                port_map['host'] = self.olt_conf['port_map']['host']
                port_map['switches'] = [ port_map['host'] ] + port_map['switches']
            else:
                port_map['host'] = port_map['switches'][0]
            nr_switches = len(port_map['switches'])
            port_map['switch_port_list'] = []
            if self.olt_conf['port_map'].has_key('ports'):
                port_map['ports'] = self.olt_conf['port_map']['ports']
                num_ports = len(port_map['ports'])
                port_map['switch_port_list'].append( (port_map['switches'][0], port_map['ports']) )
                index = 1
                for switch in port_map['switches'][1:]:
                    port_start = index * num_ports * 2
                    port_end = port_start + num_ports * 2
                    index += 1
                    port_list = []
                    for port in xrange(port_start, port_end, 2):
                        port_name = 'veth{}'.format(port)
                        port_map['ports'].append(port_name)
                        port_list.append(port_name)
                    port_map['switch_port_list'].append( (switch, port_list) )
            else:
                port_map['ports'] = []
                num_ports = int(self.olt_conf['port_map']['num_ports'])
                for sw in xrange(nr_switches):
                    port_list = []
                    switch = port_map['switches'][sw]
                    port_start = sw * num_ports * 2
                    port_end = port_start + num_ports * 2
                    for port in xrange(port_start, port_end, 2):
                        port_name = 'veth{}'.format(port)
                        port_map['ports'].append(port_name)
                        port_list.append(port_name)
                    port_map['switch_port_list'].append( (switch, port_list) )
            ##also add dhcprelay ports. We add as many relay ports as subscriber ports
            port_map['num_ports'] = num_ports
            relay_ports = num_ports
            port_map['relay_ports'] = []
            port_map['switch_relay_port_list'] = []
            port_map['radius_ports'] = []
            port_map['switch_radius_port_list'] = []
            for sw in xrange(nr_switches):
                port_list = []
                switch = port_map['switches'][sw]
                port_start = (nr_switches + sw) * relay_ports * 2
                port_end = port_start + relay_ports * 2
                for port in xrange(port_start, port_end, 2):
                    port_name = 'veth{}'.format(port)
                    port_map['relay_ports'].append(port_name)
                    port_list.append(port_name)
                port_map['switch_relay_port_list'].append( (switch, port_list) )
            for sw in xrange(nr_switches):
                switch = port_map['switches'][sw]
                if not switch.startswith('br-int'):
                    continue
                port_name = 'veth{}'.format(port_end)
                port_list = [ port_name ]
                port_map['switch_radius_port_list'].append( (switch, port_list) )
                port_map['radius_ports'].append(port_name)
                port_end += 2
            port_num = 1
            port_map['uplink'] = int(self.olt_conf['uplink'])
            port_map['wan'] = None
            if self.olt_conf.has_key('wan'):
                port_map['wan'] = self.olt_conf['wan']
            port_list = []
            ##build the port map and inverse port map
            for sw in xrange(nr_switches):
                sw_portnum = 1
                switch, ports = port_map['switch_port_list'][sw]
                uplink = sw * num_ports + port_map['uplink']
                port_map[switch] = {}
                port_map[switch]['uplink'] = uplink
                for p in ports:
                    port_map[port_num] = p
                    port_map[p] = port_num
                    if sw_portnum != port_map['uplink']:
                        #create tx, rx map
                        port_list.append( (uplink, port_num) )
                    port_num += 1
                    sw_portnum += 1
            ##build the port and inverse map for relay ports
            for port in port_map['relay_ports']:
                port_map[port_num] = port
                port_map[port] = port_num
                port_num += 1
            for port in port_map['radius_ports']:
                port_map[port_num] = port
                port_map[port] = port_num
                port_num += 1
            port_map['start_vlan'] = 0
            if self.olt_conf['port_map'].has_key('start_vlan'):
                port_map['start_vlan'] = int(self.olt_conf['port_map']['start_vlan'])

            return port_map, port_list
        else:
            return None, None

    def olt_device_data(self):
        if self.on_olt():
            accessDeviceDict = {}
            accessDeviceDict['uplink'] = str(self.olt_conf['uplink'])
            accessDeviceDict['vlan'] = str(self.olt_conf['vlan'])
            return accessDeviceDict
        return None

    def get_vcpes(self):
        if self.on_olt():
            if self.olt_conf.has_key('vcpe'):
                return self.olt_conf['vcpe']
        return []

    def get_vcpes_by_type(self, service):
        return filter(lambda vcpe: vcpe['type'].lower() == service.lower(), self.get_vcpes())
