# osmo_gsm_tester: specifics for running an Open5GS EPC
#
# Copyright (C) 2021 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
import copy

from ..core import log, util, config, template, process, remote
from ..core import schema
from . import epc
from .pcrf_open5gs import Open5gsPCRF
from .upf_open5gs import Open5gsUPF
from .smf_open5gs import Open5gsSMF
from .hss_open5gs import Open5gsHSS
from .mme_open5gs import Open5gsMME
from .sgwc_open5gs import Open5gsSGWC
from .sgwu_open5gs import Open5gsSGWU

def on_register_schemas():
    config_schema = {
        'db_host': schema.STR,
        }
    schema.register_config_schema('epc', config_schema)

class Open5gsEPC(epc.EPC):
##############
# PROTECTED
##############
    REMOTE_DIR = '/osmo-gsm-tester-open5gs'

    def __init__(self, testenv, run_node):
        super().__init__(testenv, run_node, 'open5gs_epc')
        self.run_dir = None
        self.pcrf = None
        self.upf = None
        self.smf = None
        self.mme = None
        self.hss = None
        self.sgwc = None
        self.sgwu = None
        self.subscriber_list = []

    def configure(self):
        values = super().configure(['open5gsepc'])
        db_host = values['epc']['db_host']
        db_uri = 'mongodb://'+db_host+'/open5gs'
        config.overlay(values, dict(epc=dict(db_uri=db_uri,
                                             tun_addr=self.tun_addr(),
                                             addr_smf=self.priv_addr_smf(),
                                             addr_upf=self.priv_addr_upf(),
                                             addr_sgwc=self.priv_addr_sgwc(),
                                             addr_sgwu=self.priv_addr_sgwu(),
                                             )))
        self.fill_subscribers_mongodb(values['epc']['db_host'], 27017)
        self.pcrf = Open5gsPCRF(self.testenv, self)
        self.upf = Open5gsUPF(self.testenv, self)
        self.smf = Open5gsSMF(self.testenv, self)
        self.hss = Open5gsHSS(self.testenv, self)
        self.mme = Open5gsMME(self.testenv, self)
        self.sgwc = Open5gsSGWC(self.testenv, self)
        self.sgwu = Open5gsSGWU(self.testenv, self)
        self.pcrf.configure(copy.deepcopy(values))
        self.upf.configure(copy.deepcopy(values))
        self.smf.configure(copy.deepcopy(values))
        self.hss.configure(copy.deepcopy(values))
        self.mme.configure(copy.deepcopy(values))
        self.sgwc.configure(copy.deepcopy(values))
        self.sgwu.configure(copy.deepcopy(values))

    def gen_priv_addr(self, suffix):
        if ':' in self.addr():
            raise log.Error('IPv6 not implemented!')
        public_suffix = self.addr()[self.addr().rindex('.')+1:]
        return '127.0.' + public_suffix + '.' + str(suffix)

########################
# PUBLIC - INTERNAL API
########################

    def cleanup(self):
        if self.pcrf:
            self.pcrf.cleanup()
        if self.upf:
            self.upf.cleanup()
        if self.smf:
            self.smf.cleanup()
        if self.hss:
            self.hss.cleanup()
        if self.mme:
            self.mme.cleanup()
        if self.sgwc:
            self.sgwc.cleanup()
        if self.sgwu:
            self.sgwu.cleanup()

    def priv_addr_smf(self):
        return self.gen_priv_addr(1)

    def priv_addr_upf(self):
        return self.gen_priv_addr(2)

    def priv_addr_sgwc(self):
        return self.gen_priv_addr(3)

    def priv_addr_sgwu(self):
        return self.gen_priv_addr(4)

###################
# PUBLIC (test API included)
###################
    def start(self):
        self.log('Starting srsepc')
        self.run_dir = util.Dir(self.testenv.test().get_run_dir().new_dir(self.name()))
        self.configure()
        self.pcrf.start()
        self.upf.start()
        self.smf.start()
        self.hss.start()
        self.mme.start()
        self.sgwc.start()
        self.sgwu.start()

    def subscriber_add(self, modem, msisdn=None, algo_str=None):
        if msisdn is None:
            msisdn = modem.msisdn()

        if algo_str is None:
            algo_str = modem.auth_algo() or 'milenage'

        if algo_str == 'milenage':
            if not modem.ki():
                raise log.Error("Auth algo milenage selected but no KI specified")
            if not modem.opc():
                raise log.Error("Auth algo milenage selected but no OPC specified")
        else:
            raise log.Error("Open5Gs only supports auth algo: milenage")

        subscriber_id = len(self.subscriber_list) # list index
        self.subscriber_list.append({'id': subscriber_id, 'imsi': modem.imsi(), 'msisdn': msisdn, 'auth_algo': algo_str, 'ki': modem.ki(), 'opc': modem.opc(), 'apn_ipaddr': modem.apn_ipaddr()})
        return subscriber_id

    def fill_subscribers_mongodb(self, server, port):
        import pymongo

        myclient = pymongo.MongoClient("mongodb://" + str(server) + ":" + str(port) + "/")
        mydb = myclient["open5gs"]
        mycol = mydb["subscribers"]

        for s in self.subscriber_list:
            self.log('Insert subscriber to DB', msisdn=s['msisdn'], imsi=s['imsi'], subscriber_id=s['id'],
                     algo_str=s['auth_algo'])
            slice_data = [ { \
                "sst": 1, \
                "default_indicator": True, \
                "session": [ \
                    { \
                    "name": "internet", \
                    "type": 3, "pcc_rule": [], "ambr": {"uplink": {"value": 1, "unit": 0}, "downlink": {"value": 1, "unit": 0}}, \
                    "qos": { "index": 9, "arp": {"priority_level": 8, "pre_emption_capability": 1, "pre_emption_vulnerability": 1} } \
                    } \
                ] \
            } ]

            sub_data = {'imsi':  s['imsi'], \
                        'subscribed_rau_tau_timer': 12, \
                        'network_access_mode': 2, \
                        'subscriber_status': 0, \
                        "access_restriction_data": 32, \
                        'slice': slice_data, \
                        'ambr': {"uplink": {"value": 1, "unit": 0}, "downlink": {"value": 1, "unit": 0}}, \
                        'security': {'k': s['ki'], 'amf': '8000', 'op': None, 'opc': s['opc']},
                        'schema_version': 1, \
                        '__v': 0}
            x = mycol.insert_one(sub_data)
            self.dbg("Added subscriber with Inserted ID : " + str(x.inserted_id))
            s['inserted_id'] = x.inserted_id

    def enb_is_connected(self, enb):
        # Match against sample mmed line: "eNB-S1 accepted[172.18.50.101]:50867"
        if not self.mme or not self.mme.running():
            return False
        stdout_lines = (self.mme.process.get_stdout() or '').splitlines()
        for l in stdout_lines:
            if 'eNB' in l and 'accepted' in l and enb.addr() in l:
                return True
        return False

    def running(self):
        return self.pcrf and self.upf and self.smf and self.hss and \
               self.mme and self.sgwc and self.sgwu and \
               self.pcrf.running() and self.upf.running() and self.smf.running() and \
               self.hss.running() and self.mme.running() and self.sgwc.running() and \
               self.sgwu.running()

    def tun_addr(self):
        return '172.16.0.1'

    def get_kpis(self):
        return {}

# vim: expandtab tabstop=4 shiftwidth=4
