# 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[].enb_id': schema.UINT,
        'cell_list[].ncell_list[].cell_id': schema.UINT,
        'cell_list[].ncell_list[].pci': schema.UINT,
        'cell_list[].ncell_list[].dl_earfcn': schema.UINT,
        'cell_list[].scell_list[]': schema.UINT,
        'cell_list[].dl_earfcn': schema.UINT,
        'cell_list[].root_seq_idx': schema.UINT,
        'cell_list[].tac': 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
