# osmo_gsm_tester: specifics for running a osmo-pcu for OC-2G
#
# 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
from . import pcu

class OsmoPcuOC2G(pcu.Pcu):

    REMOTE_DIR = '/osmo-gsm-tester-pcu'
    PCU_OC2G_BIN = 'osmo-pcu'
    PCU_OC2G_CFG = 'osmo-pcu-oc2g.cfg'

    def __init__(self, suite_run, btsoc2g, conf):
        super().__init__(suite_run, btsoc2g, conf, self.PCU_OC2G_BIN)
        self.run_dir = None
        self.bsc = None
        self.inst = None
        self.remote_inst = None
        self.remote_dir = None
        self.remote_env = {}
        self.remote_user = 'root'

    def start(self, keepalive=False):
        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('osmo-pcu-oc2g')))
        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', OsmoPcuOC2G.PCU_OC2G_BIN):
            raise log.Error('No osmo-pcu-oc2g binary in', self.inst)

        self.remote_dir = util.Dir(OsmoPcuOC2G.REMOTE_DIR)
        self.remote_inst = util.Dir(self.remote_dir.child(os.path.basename(str(self.inst))))

        self.run_remote('rm-remote-dir', ('test', '!', '-d', OsmoPcuOC2G.REMOTE_DIR, '||', 'rm', '-rf', OsmoPcuOC2G.REMOTE_DIR))
        self.run_remote('mk-remote-dir', ('mkdir', '-p', OsmoPcuOC2G.REMOTE_DIR))
        self.run_local('scp-inst-to-btsoc2g',
            ('scp', '-r', str(self.inst), '%s@%s:%s' % (self.remote_user, self.bts.remote_addr(), str(self.remote_inst))))

        remote_run_dir = self.remote_dir.child(OsmoPcuOC2G.PCU_OC2G_BIN)
        self.run_remote('mk-remote-run-dir', ('mkdir', '-p', remote_run_dir))

        remote_config_file = self.remote_dir.child(OsmoPcuOC2G.PCU_OC2G_CFG)
        self.run_local('scp-cfg-to-btsoc2g',
            ('scp', '-r', self.config_file, '%s@%s:%s' % (self.remote_user, self.bts.remote_addr(), remote_config_file)))

        remote_lib = self.remote_inst.child('lib')
        remote_binary = self.remote_inst.child('bin', OsmoPcuOC2G.PCU_OC2G_BIN)
        self.launch_remote(OsmoPcuOC2G.PCU_OC2G_BIN,
            ('LD_LIBRARY_PATH=%s' % remote_lib,
             remote_binary, '-c', remote_config_file, '-r', '1',
             '-i', self.bts.bsc.addr()),
            remote_cwd=remote_run_dir, keepalive=keepalive)

    def _process_remote(self, name, popen_args, remote_cwd=None):
        run_dir = self.run_dir.new_dir(name)
        return process.RemoteProcess(name, run_dir, self.remote_user, self.bts.remote_addr(), remote_cwd,
                                     popen_args)

    def run_remote(self, name, popen_args, remote_cwd=None):
        proc = self._process_remote(name, popen_args, remote_cwd)
        proc.launch()
        proc.wait()
        if proc.result != 0:
            log.ctx(proc)
            raise log.Error('Exited in error')

    def launch_remote(self, name, popen_args, remote_cwd=None, keepalive=False):
        proc = self._process_remote(name, popen_args, remote_cwd)
        self.suite_run.remember_to_stop(proc, keepalive)
        proc.launch()

    def run_local(self, name, popen_args):
        run_dir = self.run_dir.new_dir(name)
        proc = process.Process(name, run_dir, popen_args)
        proc.launch()
        proc.wait()
        if proc.result != 0:
            log.ctx(proc)
            raise log.Error('Exited in error')

    def configure(self):
        self.config_file = self.run_dir.new_file(OsmoPcuOC2G.PCU_OC2G_CFG)
        self.dbg(config_file=self.config_file)

        values = { 'osmo_pcu_oc2g': config.get_defaults('osmo_pcu_oc2g') }
        config.overlay(values, self.suite_run.config())
        config.overlay(values, {
                        'osmo_pcu_oc2g': {
                            'bts_addr': self.bts.remote_addr(),
                            'pcu_socket_path': self.bts.pcu_socket_path(),
                            'egprs_enabled': self.egprs_enabled(),
                        }
        })
        config.overlay(values, { 'osmo_pcu_oc2g': self.conf })

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

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

# vim: expandtab tabstop=4 shiftwidth=4
