# osmo_gsm_tester: base classes to share code among eNodeB subclasses.
#
# Copyright (C) 2020 by sysmocom - s.f.m.c. GmbH
#
# Author: Pau Espin Pedrol <pespin@sysmocom.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from abc import ABCMeta, abstractmethod
from ..core import log, config
from ..core import schema
from . import run_node
from .gnuradio_zmq_broker import GrBroker

def on_register_schemas():
    resource_schema = {
        'label': schema.STR,
        'type': schema.STR,
        'gtp_bind_addr': schema.IPV4,
        'id': schema.UINT,
        'num_prb': schema.UINT,
        'duplex': schema.STR,
        'tdd_uldl_config': schema.UINT,
        'tdd_special_subframe_pattern': schema.UINT,
        'transmission_mode': schema.LTE_TRANSMISSION_MODE,
        'tx_gain': schema.UINT,
        'rx_gain': schema.UINT,
        'rf_dev_type': schema.STR,
        'rf_dev_args': schema.STR,
        'rf_dev_sync': schema.STR,
        'additional_args[]': schema.STR,
        'inactivity_timer': schema.INT,
        'enable_measurements': schema.BOOL_STR,
        'enable_dl_awgn': schema.BOOL_STR,
        'dl_awgn_snr': schema.INT,
        'a1_report_type': schema.STR,
        'a1_report_value': schema.INT,
        'a1_hysteresis': schema.INT,
        'a1_time_to_trigger': schema.INT,
        'a2_report_type': schema.STR,
        'a2_report_value': schema.INT,
        'a2_hysteresis': schema.INT,
        'a2_time_to_trigger': schema.INT,
        'a3_report_type': schema.STR,
        'a3_report_value': schema.INT,
        'a3_hysteresis': schema.INT,
        'a3_time_to_trigger': schema.INT,
        'num_cells': schema.UINT,
        'cell_list[].cell_id': schema.UINT,
        'cell_list[].rf_port': schema.UINT,
        'cell_list[].pci': schema.UINT,
        'cell_list[].ncell_list[]': schema.UINT,
        'cell_list[].scell_list[]': schema.UINT,
        'cell_list[].dl_earfcn': schema.UINT,
        'cell_list[].dl_rfemu.type': schema.STR,
        'cell_list[].dl_rfemu.addr': schema.IPV4,
        'cell_list[].dl_rfemu.ports[]': schema.UINT,
        }
    for key, val in run_node.RunNode.schema().items():
        resource_schema['run_node.%s' % key] = val
    schema.register_resource_schema('enb', resource_schema)

class eNodeB(log.Origin, metaclass=ABCMeta):

##############
# PROTECTED
##############
    def __init__(self, testenv, conf, name):
        super().__init__(log.C_RUN, '%s' % name)
        self._conf = conf
        self._run_node = run_node.RunNode.from_conf(conf.get('run_node', {}))
        self._gtp_bind_addr = conf.get('gtp_bind_addr', None)
        if self._gtp_bind_addr is None:
            self._gtp_bind_addr = self._run_node.run_addr()
        label = conf.get('label', None)
        self.set_name('%s_%s' % (name, label if label is not None else self._run_node.run_addr()))
        self._txmode = 0
        self._id = None
        self._duplex = None
        self._num_prb = 0
        self._num_cells = None
        self._epc = None
        self.gen_conf = None
        self.gr_broker = GrBroker.ref()
        self.gr_broker.register_enb(self)
        self._use_gr_broker = False

    def using_grbroker(self, cfg_values):
        # whether we are to use Grbroker in between ENB and UE.
        # Initial checks:
        if cfg_values['enb'].get('rf_dev_type') != 'zmq':
            return False
        cell_list = cfg_values['enb']['cell_list']
        use_match = False
        notuse_match = False
        for cell in cell_list:
            if cell.get('dl_rfemu', False) and cell['dl_rfemu'].get('type', None) == 'gnuradio_zmq':
                use_match = True
            else:
                notuse_match = True
        if use_match and notuse_match:
            raise log.Error('Some Cells are configured to use gnuradio_zmq and some are not, unsupported')
        return use_match

    def calc_required_zmq_ports(self, cfg_values):
        cell_list = cfg_values['enb']['cell_list']
        return len(cell_list) * self.num_ports() # *2 if MIMO

    def calc_required_zmq_ports_joined_earfcn(self, cfg_values):
        #gr_broker will join the earfcns, so we need to count uniqe earfcns:
        cell_list = cfg_values['enb']['cell_list']
        earfcn_li = []
        [earfcn_li.append(int(cell['dl_earfcn'])) for cell in cell_list if int(cell['dl_earfcn']) not in earfcn_li]
        return len(earfcn_li) * self.num_ports() # *2 if MIMO


    def assign_enb_zmq_ports(self, cfg_values, port_name, base_port):
        port_offset = 0
        cell_list = cfg_values['enb']['cell_list']
        for cell in cell_list:
            cell[port_name] = base_port + port_offset
            port_offset += self.num_ports()
        # TODO: do we need to assign cell_list back?

    def assign_enb_zmq_ports_joined_earfcn(self, cfg_values, port_name, base_port):
        # TODO: Set in cell one bind port per unique earfcn, this is where UE will connect to when we use grbroker.
        cell_list = cfg_values['enb']['cell_list']
        earfcn_li = []
        [earfcn_li.append(int(cell['dl_earfcn'])) for cell in cell_list if int(cell['dl_earfcn']) not in earfcn_li]
        for cell in cell_list:
            cell[port_name] = base_port + earfcn_li.index(int(cell['dl_earfcn'])) * self.num_ports()

    def configure(self, config_specifics_li):
        values = dict(enb=config.get_defaults('enb'))
        for config_specifics in config_specifics_li:
            config.overlay(values, dict(enb=config.get_defaults(config_specifics)))
        config.overlay(values, dict(enb=self.testenv.suite().config().get('enb', {})))
        for config_specifics in config_specifics_li:
            config.overlay(values, dict(enb=self.testenv.suite().config().get(config_specifics, {})))
        config.overlay(values, dict(enb=self._conf))
        self._id = int(values['enb'].get('id', None))
        assert self._id is not None
        self._duplex = values['enb'].get('duplex', None)
        assert self._duplex
        self._num_prb = int(values['enb'].get('num_prb', None))
        assert self._num_prb
        self._txmode = int(values['enb'].get('transmission_mode', None))
        assert self._txmode
        config.overlay(values, dict(enb={ 'num_ports': self.num_ports() }))
        self._inactivity_timer = int(values['enb'].get('inactivity_timer', None))
        assert self._inactivity_timer
        assert self._epc is not None
        config.overlay(values, dict(enb={ 'addr': self.addr() }))
        config.overlay(values, dict(enb={ 'mme_addr': self._epc.addr() }))
        config.overlay(values, dict(enb={ 'gtp_bind_addr': self._gtp_bind_addr }))
        self._num_cells = int(values['enb'].get('num_cells', None))
        assert self._num_cells

        # adjust cell_list to num_cells length:
        len_cell_list = len(values['enb']['cell_list'])
        if len_cell_list >= self._num_cells:
            values['enb']['cell_list'] = values['enb']['cell_list'][:self._num_cells]
        else:
            raise log.Error('enb.cell_list items (%d) < enb.num_cells (%d) attribute!' % (len_cell_list, self._num_cells))
        # adjust scell list (to only contain values available in cell_list):
        cell_id_list = [c['cell_id'] for c in values['enb']['cell_list']]
        for i in range(len(values['enb']['cell_list'])):
            scell_list_old = values['enb']['cell_list'][i]['scell_list']
            scell_list_new = []
            for scell_id in scell_list_old:
                if scell_id in cell_id_list:
                    scell_list_new.append(scell_id)
            values['enb']['cell_list'][i]['scell_list'] = scell_list_new

        # Assign ZMQ ports to each Cell/EARFCN.
        if values['enb'].get('rf_dev_type') == 'zmq':
            resourcep = self.testenv.suite().resource_pool()
            num_ports = self.calc_required_zmq_ports(values)
            num_ports_joined_earfcn = self.calc_required_zmq_ports_joined_earfcn(values)
            ue_bind_port = self.ue.zmq_base_bind_port()
            enb_bind_port = resourcep.next_zmq_port_range(self, num_ports)
            self.assign_enb_zmq_ports(values, 'zmq_enb_bind_port', enb_bind_port)
            # If we are to use a GrBroker, then initialize here to have remote zmq ports available:
            self._use_gr_broker = self.using_grbroker(values)
            if self._use_gr_broker:
                zmq_enb_peer_port = resourcep.next_zmq_port_range(self, num_ports)
                self.assign_enb_zmq_ports(values, 'zmq_enb_peer_port', zmq_enb_peer_port) # These are actually bound to GrBroker
                self.assign_enb_zmq_ports_joined_earfcn(values, 'zmq_ue_bind_port', ue_bind_port) # This is were GrBroker binds on the UE side
                zmq_ue_peer_port = resourcep.next_zmq_port_range(self, num_ports_joined_earfcn)
                self.assign_enb_zmq_ports_joined_earfcn(values, 'zmq_ue_peer_port', zmq_ue_peer_port) # This is were GrBroker binds on the UE side
                # Already set gen_conf here in advance since gr_broker needs the cell list
                self.gen_conf = values
                self.gr_broker.start()
            else:
                self.assign_enb_zmq_ports(values, 'zmq_enb_peer_port', ue_bind_port)
                self.assign_enb_zmq_ports(values, 'zmq_ue_bind_port', ue_bind_port) #If no broker we need to match amount of ports
                self.assign_enb_zmq_ports(values, 'zmq_ue_peer_port', enb_bind_port)

        return values

    def id(self):
        return self._id

    def num_ports(self):
        if self._txmode == 1:
            return 1
        return 2

    def num_cells(self):
        return self._num_cells

########################
# PUBLIC - INTERNAL API
########################
    def cleanup(self):
        'Nothing to do by default. Subclass can override if required.'
        if self.gr_broker:
            self.gr_broker.unregister_enb(self)
            GrBroker.unref()
            self.gr_broker = None

    def num_prb(self):
        return self._num_prb

    #reference: srsLTE.git srslte_symbol_sz()
    def num_prb2symbol_sz(self, num_prb):
        if num_prb == 6:
            return 128
        if num_prb == 50:
            return 768
        if num_prb == 75:
            return 1024
        return 1536

        raise log.Error('invalid num_prb %r', num_prb)

    def num_prb2base_srate(self, num_prb):
        return self.num_prb2symbol_sz(num_prb) * 15 * 1000

    def get_zmq_rf_dev_args(self, cfg_values):
        base_srate = self.num_prb2base_srate(self.num_prb())

        if self._use_gr_broker:
            ul_rem_addr = self.gr_broker.addr()
        else:
            ul_rem_addr = self.ue.addr()

        rf_dev_args = 'fail_on_disconnect=true'
        idx = 0
        cell_list = cfg_values['enb']['cell_list']
        # Define all 8 possible RF ports (2x CA with 2x2 MIMO)
        for cell in cell_list:
            rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx, self.addr(), cell['zmq_enb_bind_port'] + 0)
            if self.num_ports() > 1:
                rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx + 1, self.addr(), cell['zmq_enb_bind_port'] + 1)
            rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx, ul_rem_addr, cell['zmq_enb_peer_port'] + 0)
            if self.num_ports() > 1:
                rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx + 1, ul_rem_addr, cell['zmq_enb_peer_port'] + 1)
            idx += self.num_ports()

        rf_dev_args += ',id=enb,base_srate=' + str(base_srate)
        return rf_dev_args

    def get_zmq_rf_dev_args_for_ue(self, ue):
        cell_list = self.gen_conf['enb']['cell_list']
        rf_dev_args = ''
        idx = 0
        earfcns_done = []
        for cell in cell_list:
            if self._use_gr_broker:
                if cell['dl_earfcn'] in earfcns_done:
                    continue
                earfcns_done.append(cell['dl_earfcn'])
            rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx, ue.addr(), cell['zmq_ue_bind_port'] + 0)
            if self.num_ports() > 1:
                rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx + 1, ue.addr(), cell['zmq_ue_bind_port'] + 1)
            rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx, self.addr(), cell['zmq_ue_peer_port'] + 0)
            if self.num_ports() > 1:
                rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx + 1, self.addr(), cell['zmq_ue_peer_port'] + 1)
            idx += self.num_ports()
        # remove trailing comma:
        if rf_dev_args[0] == ',':
            return rf_dev_args[1:]
        return rf_dev_args

    def get_instance_by_type(testenv, conf):
        """Allocate a ENB child class based on type. Opts are passed to the newly created object."""
        enb_type = conf.get('type')
        if enb_type is None:
            raise RuntimeError('ENB type is not defined!')

        if enb_type == 'amarisoftenb':
            from .enb_amarisoft import AmarisoftENB
            enb_class = AmarisoftENB
        elif enb_type == 'srsenb':
            from .enb_srs import srsENB
            enb_class = srsENB
        else:
            raise log.Error('ENB type not supported:', enb_type)
        return  enb_class(testenv, conf)

###################
# PUBLIC (test API included)
###################
    @abstractmethod
    def start(self, epc):
        'Starts ENB, it will connect to "epc"'
        pass

    @abstractmethod
    def ue_add(self, ue):
        pass

    @abstractmethod
    def running(self):
        pass

    @abstractmethod
    def ue_max_rate(self, downlink=True, num_carriers=1):
        pass

    @abstractmethod
    def get_rfemu(self, cell=0, dl=True):
        'Get rfemu.RFemulation subclass implementation object for given cell index and direction.'
        pass

    def addr(self):
        return self._run_node.run_addr()

# vim: expandtab tabstop=4 shiftwidth=4
