# osmo_gsm_tester: specifics for running a osmo-bts-oc2g
#
# Copyright (C) 2019 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/>.

import os
import pprint
from .core import log, config, util, template, process, remote
from . import pcu_oc2g, bts_osmo

class OsmoBtsOC2G(bts_osmo.OsmoBts):
##############
# PROTECTED
##############

    REMOTE_DIR = '/osmo-gsm-tester-bts'
    BTS_OC2G_BIN = 'osmo-bts-oc2g'
    BTS_OC2G_CFG = 'osmo-bts-oc2g.cfg'

    def __init__(self, suite_run, conf):
        super().__init__(suite_run, conf, OsmoBtsOC2G.BTS_OC2G_BIN, 'osmo_bts_oc2g')
        self.run_dir = None
        self.inst = None
        self.remote_inst = None
        self.remote_dir = None
        self.proc_bts = None
        self.remote_user = 'root'

    def _direct_pcu_enabled(self):
        return util.str2bool(self.conf.get('direct_pcu'))

    def create_pcu(self):
        return pcu_oc2g.OsmoPcuOC2G(self.suite_run, self, self.conf)

    def configure(self):
        if self.bsc is None:
            raise RuntimeError('BTS needs to be added to a BSC or NITB before it can be configured')

        self.config_file = self.run_dir.new_file(OsmoBtsOC2G.BTS_OC2G_CFG)
        self.dbg(config_file=self.config_file)

        values = { 'osmo_bts_oc2g': config.get_defaults('osmo_bts_oc2g') }
        config.overlay(values, self.suite_run.config())
        config.overlay(values, {
                        'osmo_bts_oc2g': {
                            'oml_remote_ip': self.bsc.addr(),
                            'pcu_socket_path': self.pcu_socket_path(),
                        }
        })
        config.overlay(values, { 'osmo_bts_oc2g': self.conf })

        self.dbg('OSMO-BTS-OC2G CONFIG:\n' + pprint.pformat(values))

        with open(self.config_file, 'w') as f:
            r = template.render(OsmoBtsOC2G.BTS_OC2G_CFG, values)
            self.dbg(r)
            f.write(r)

########################
# PUBLIC - INTERNAL API
########################
    def pcu_socket_path(self):
        return os.path.join(OsmoBtsOC2G.REMOTE_DIR, 'pcu_bts')

    def conf_for_bsc(self):
        values = self.conf_for_bsc_prepare()
        # Hack until we have proper ARFCN resource allocation support (OS#2230)
        band = values.get('band')
        trx_list = values.get('trx_list')
        if band == 'GSM-900':
            for trx_i in range(len(trx_list)):
                config.overlay(trx_list[trx_i], { 'arfcn' : str(50 + trx_i * 2) })
        self.dbg(conf=values)
        return values

###################
# PUBLIC (test API included)
###################
    # We get log from ssh stdout instead of usual stderr.
    def ready_for_pcu(self):
        if not self.proc_bts or not self.proc_bts.is_running:
            return False
        return 'BTS is up' in (self.proc_bts.get_stdout() or '')

    def start(self, keepalive=False):
        if self.bsc is None:
            raise RuntimeError('BTS needs to be added to a BSC or NITB before it can be started')
        log.log('Starting OsmoBtsOC2G to connect to', self.bsc)
        self.run_dir = util.Dir(self.suite_run.get_test_run_dir().new_dir(self.name()))
        self.configure()

        self.inst = util.Dir(os.path.abspath(self.suite_run.trial.get_inst(OsmoBtsOC2G.BTS_OC2G_BIN)))
        lib = self.inst.child('lib')
        if not os.path.isdir(lib):
            raise log.Error('No lib/ in', self.inst)
        if not self.inst.isfile('bin', OsmoBtsOC2G.BTS_OC2G_BIN):
            raise log.Error('No osmo-bts-oc2g binary in', self.inst)

        rem_host = remote.RemoteHost(self.run_dir, self.remote_user, self.remote_addr())
        remote_prefix_dir = util.Dir(OsmoBtsOC2G.REMOTE_DIR)
        self.remote_inst = util.Dir(remote_prefix_dir.child(os.path.basename(str(self.inst))))
        remote_run_dir = util.Dir(remote_prefix_dir.child(OsmoBtsOC2G.BTS_OC2G_BIN))
        remote_config_file = remote_run_dir.child(OsmoBtsOC2G.BTS_OC2G_CFG)

        rem_host.recreate_remote_dir(self.remote_inst)
        rem_host.scp('scp-inst-to-remote', str(self.inst), remote_prefix_dir)
        rem_host.create_remote_dir(remote_run_dir)
        rem_host.scp('scp-cfg-to-remote', self.config_file, remote_config_file)

        remote_lib = self.remote_inst.child('lib')
        remote_binary = self.remote_inst.child('bin', OsmoBtsOC2G.BTS_OC2G_BIN)
        args = ('LD_LIBRARY_PATH=%s' % remote_lib,
         remote_binary, '-c', remote_config_file, '-r', '1',
         '-i', self.bsc.addr())

        if self._direct_pcu_enabled():
            args += ('-M',)

        self.proc_bts = rem_host.RemoteProcess(OsmoBtsOC2G.BTS_OC2G_BIN, args)
        self.suite_run.remember_to_stop(self.proc_bts, keepalive)
        self.proc_bts.launch()
# vim: expandtab tabstop=4 shiftwidth=4
