# osmo_gsm_tester: validate dict structures
#
# Copyright (C) 2016-2017 by sysmocom - s.f.m.c. GmbH
#
# Author: Neels Hofmeyr <neels@hofmeyr.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 re
import os

from . import log
from . import util

KEY_RE = re.compile('[a-zA-Z0-9][a-zA-Z0-9_]*')
IPV4_RE = re.compile('([0-9]{1,3}.){3}[0-9]{1,3}')
HWADDR_RE = re.compile('([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}')
IMSI_RE = re.compile('[0-9]{6,15}')
KI_RE = re.compile('[0-9a-fA-F]{32}')
OPC_RE = re.compile('[0-9a-fA-F]{32}')
MSISDN_RE = re.compile('[0-9]{1,15}')

def match_re(name, regex, val):
    while True:
        if not isinstance(val, str):
            break;
        if not regex.fullmatch(val):
            break;
        return True
    raise ValueError('Invalid %s: %r' % (name, val))

def band(val):
    if val in ('GSM-900', 'GSM-1800', 'GSM-1900'):
        return True
    raise ValueError('Unknown GSM band: %r' % val)

def ipv4(val):
    match_re('IPv4 address', IPV4_RE, val)
    els = [int(el) for el in val.split('.')]
    if not all([el >= 0 and el <= 255 for el in els]):
        raise ValueError('Invalid IPv4 address: %r' % val)
    return True

def hwaddr(val):
    return match_re('hardware address', HWADDR_RE, val)

def imsi(val):
    return match_re('IMSI', IMSI_RE, val)

def ki(val):
    return match_re('KI', KI_RE, val)

def opc(val):
    return match_re('OPC', OPC_RE, val)

def msisdn(val):
    return match_re('MSISDN', MSISDN_RE, val)

def auth_algo(val):
    if val not in util.ENUM_OSMO_AUTH_ALGO:
        raise ValueError('Unknown Authentication Algorithm: %r' % val)
    return True

def uint(val):
    n = int(val)
    if n < 0:
        raise ValueError('Positive value expected instead of %d' % n)
    return True

def uint8(val):
    n = int(val)
    if n < 0:
        raise ValueError('Positive value expected instead of %d' % n)
    if n > 255: # 2^8 - 1
        raise ValueError('Value %d too big, max value is 255' % n)
    return True

def uint16(val):
    n = int(val)
    if n < 0:
        raise ValueError('Positive value expected instead of %d' % n)
    if n > 65535: # 2^16 - 1
        raise ValueError('Value %d too big, max value is 65535' % n)
    return True

def bool_str(val):
    # str2bool will raise an exception if unable to parse it
    util.str2bool(val)
    return True

def times(val):
    n = int(val)
    if n < 1:
        raise ValueError('Positive value >0 expected instead of %d' % n)
    return True

def cipher(val):
    if val in ('a5_0', 'a5_1', 'a5_2', 'a5_3', 'a5_4', 'a5_5', 'a5_6', 'a5_7'):
        return True
    raise ValueError('Unknown Cipher value: %r' % val)

def modem_feature(val):
    if val in ('sms', 'gprs', 'voice', 'ussd', 'sim', '2g', '3g', '4g'):
        return True
    raise ValueError('Unknown Modem Feature: %r' % val)

def phy_channel_config(val):
    if val in ('CCCH', 'CCCH+SDCCH4', 'TCH/F', 'TCH/H', 'SDCCH8', 'PDCH',
               'TCH/F_PDCH', 'CCCH+SDCCH4+CBCH', 'SDCCH8+CBCH','TCH/F_TCH/H_PDCH'):
        return True
    raise ValueError('Unknown Physical channel config: %r' % val)

def channel_allocator(val):
    if val in ('ascending', 'descending'):
        return True
    raise ValueError('Unknown Channel Allocator Policy %r' % val)

def gprs_mode(val):
    if val in ('none', 'gprs', 'egprs'):
        return True
    raise ValueError('Unknown GPRS mode %r' % val)

def codec(val):
    if val in ('hr1', 'hr2', 'hr3', 'fr1', 'fr2', 'fr3'):
        return True
    raise ValueError('Unknown Codec value: %r' % val)

def osmo_trx_clock_ref(val):
    if val in ('internal', 'external', 'gspdo'):
        return True
    raise ValueError('Unknown OsmoTRX clock reference value: %r' % val)

def lte_transmission_mode(val):
    n = int(val)
    if n <= 4:
        return True
    raise ValueError('LTE Transmission Mode %d not in expected range' % n)

def duration(val):
    if val.isdecimal() or val.endswith('m') or val.endswith('h'):
        return True
    raise ValueError('Invalid duration value: %r' % val)

INT = 'int'
STR = 'str'
UINT = 'uint'
BOOL_STR = 'bool_str'
BAND = 'band'
IPV4 = 'ipv4'
HWADDR = 'hwaddr'
IMSI = 'imsi'
KI = 'ki'
OPC = 'opc'
MSISDN = 'msisdn'
AUTH_ALGO = 'auth_algo'
TIMES='times'
CIPHER = 'cipher'
MODEM_FEATURE = 'modem_feature'
PHY_CHAN = 'chan'
CHAN_ALLOCATOR = 'chan_allocator'
GPRS_MODE = 'gprs_mode'
CODEC = 'codec'
OSMO_TRX_CLOCK_REF = 'osmo_trx_clock_ref'
LTE_TRANSMISSION_MODE = 'lte_transmission_mode'
DURATION = 'duration'

SCHEMA_TYPES = {
        INT: int,
        STR: str,
        UINT: uint,
        BOOL_STR: bool_str,
        BAND: band,
        IPV4: ipv4,
        HWADDR: hwaddr,
        IMSI: imsi,
        KI: ki,
        OPC: opc,
        MSISDN: msisdn,
        AUTH_ALGO: auth_algo,
        TIMES: times,
        CIPHER: cipher,
        MODEM_FEATURE: modem_feature,
        PHY_CHAN: phy_channel_config,
        CHAN_ALLOCATOR: channel_allocator,
        GPRS_MODE: gprs_mode,
        CODEC: codec,
        OSMO_TRX_CLOCK_REF: osmo_trx_clock_ref,
        LTE_TRANSMISSION_MODE: lte_transmission_mode,
        DURATION: duration,
    }

def add(dest, src):
    if util.is_dict(dest):
        if not util.is_dict(src):
            raise ValueError('cannot add to dict a value of type: %r' % type(src))

        for key, val in src.items():
            dest_val = dest.get(key)
            if dest_val is None:
                dest[key] = val
            else:
                log.ctx(key=key)
                add(dest_val, val)
        return
    if util.is_list(dest):
        if not util.is_list(src):
            raise ValueError('cannot add to list a value of type: %r' % type(src))
        dest.extend(src)
        return
    if dest == src:
        return
    raise ValueError('cannot add dicts, conflicting items (values %r and %r)'
                     % (dest, src))

def combine(dest, src):
    if util.is_dict(dest):
        if not util.is_dict(src):
            raise ValueError('cannot combine dict with a value of type: %r' % type(src))

        for key, val in src.items():
            log.ctx(key=key)
            dest_val = dest.get(key)
            if dest_val is None:
                dest[key] = val
            else:
                combine(dest_val, val)
        return
    if util.is_list(dest):
        if not util.is_list(src):
            raise ValueError('cannot combine list with a value of type: %r' % type(src))
        # Validate that all elements in both lists are of the same type:
        t = util.list_validate_same_elem_type(src + dest)
        if t is None:
            return # both lists are empty, return
        # For lists of complex objects, we expect them to be sorted lists:
        if t in (dict, list, tuple):
            for i in range(len(dest)):
                log.ctx(idx=i)
                src_it = src[i] if i < len(src) else util.empty_instance_type(t)
                combine(dest[i], src_it)
            for i in range(len(dest), len(src)):
                log.ctx(idx=i)
                dest.append(src[i])
        else: # for lists of basic elements, we handle them as unsorted sets:
            for elem in src:
                if elem not in dest:
                    dest.append(elem)
        return
    if dest == src:
        return
    raise ValueError('cannot combine dicts, conflicting items (values %r and %r)'
                     % (dest, src))

def replicate_times(d):
    '''
    replicate items that have a "times" > 1

    'd' is a dict matching WANT_SCHEMA, which is the same as
    the RESOURCES_SCHEMA, except each entity that can be reserved has a 'times'
    field added, to indicate how many of those should be reserved.
    '''
    d = copy.deepcopy(d)
    for key, item_list in d.items():
        idx = 0
        while idx < len(item_list):
            item = item_list[idx]
            times = int(item.pop('times', 1))
            for j in range(1, times):
                item_list.insert(idx + j, copy.deepcopy(item))
            idx += times
    return d

def validate(config, schema):
    '''Make sure the given config dict adheres to the schema.
       The schema is a dict of 'dict paths' in dot-notation with permitted
       value type. All leaf nodes are validated, nesting dicts are implicit.

       validate( { 'a': 123, 'b': { 'b1': 'foo', 'b2': [ 1, 2, 3 ] } },
                 { 'a': int,
                   'b.b1': str,
                   'b.b2[]': int } )

       Raise a ValueError in case the schema is violated.
    '''

    def validate_item(path, value, schema):
        want_type = schema.get(path)

        if util.is_list(value):
            if want_type:
                raise ValueError('config item is a list, should be %r: %r' % (want_type, path))
            path = path + '[]'
            want_type = schema.get(path)

        if not want_type:
            if util.is_dict(value):
                nest(path, value, schema)
                return
            if util.is_list(value) and value:
                for list_v in value:
                    validate_item(path, list_v, schema)
                return
            raise ValueError('config item not known: %r' % path)

        if want_type not in SCHEMA_TYPES:
            raise ValueError('unknown type %r at %r' % (want_type, path))

        if util.is_dict(value):
            raise ValueError('config item is dict but should be a leaf node of type %r: %r'
                             % (want_type, path))

        if util.is_list(value):
            for list_v in value:
                validate_item(path, list_v, schema)
            return

        log.ctx(path)
        type_validator = SCHEMA_TYPES.get(want_type)
        valid = type_validator(value)
        if not valid:
            raise ValueError('Invalid value %r for schema type \'%s\' (validator: %s)' % (value, want_type, type_validator.__name__))

    def nest(parent_path, config, schema):
        if parent_path:
            parent_path = parent_path + '.'
        else:
            parent_path = ''
        for k,v in config.items():
            if not KEY_RE.fullmatch(k):
                raise ValueError('invalid config key: %r' % k)
            path = parent_path + k
            validate_item(path, v, schema)

    nest(None, config, schema)

def config_to_schema_def(src, key_prefix):
    'Converts a yaml parsed config into a schema dictionary used by validate()'
    if util.is_dict(src):
        out_dict = {}
        for key, val in src.items():
            list_token = ''
            dict_token = ''
            if util.is_list(val):
                list_token = '[]'
                assert len(val) == 1
                val = val[0]
            if util.is_dict(val):
                dict_token = '.'
            tmp_out = config_to_schema_def(val, "%s%s%s%s" %(key_prefix, key, list_token, dict_token))
            out_dict = {**out_dict, **tmp_out}
        return out_dict

    # base case: string
    return {key_prefix: str(src)}


def generate_schemas():
    "Generate supported schemas dynamically from objects"
    obj_dir = '%s/../obj/' % os.path.dirname(os.path.abspath(__file__))
    for filename in os.listdir(obj_dir):
        if not filename.endswith(".py"):
            continue
        module_name = 'osmo_gsm_tester.obj.%s' % filename[:-3]
        util.run_python_file_method(module_name, 'on_register_schemas', False)


_RESOURCE_TYPES = ['ip_address', 'arfcn']

_RESOURCES_SCHEMA = {
        'ip_address[].addr': IPV4,
        'arfcn[].arfcn': INT,
        'arfcn[].band': BAND,
    }

_CONFIG_SCHEMA = {}

_WANT_SCHEMA = None
_ALL_SCHEMA = None

def register_schema_types(schema_type_attr):
    """Register schema types to be used by schema attributes.
       For instance: register_resource_schema_attributes({ 'fruit': lambda val: val in ('banana', 'apple') })
    """
    global SCHEMA_TYPES
    combine(SCHEMA_TYPES, schema_type_attr)

def register_resource_schema(obj_class_str, obj_attr_dict):
    """Register schema attributes for a resource type.
       For instance: register_resource_schema_attributes('modem', {'type': schema.STR, 'ki': schema.KI})
    """
    global _RESOURCES_SCHEMA
    global _RESOURCE_TYPES
    tmpdict = {}
    for key, val in obj_attr_dict.items():
        new_key = '%s[].%s' % (obj_class_str, key)
        tmpdict[new_key] = val
    combine(_RESOURCES_SCHEMA, tmpdict)
    if obj_class_str not in _RESOURCE_TYPES:
        _RESOURCE_TYPES.append(obj_class_str)

def register_config_schema(obj_class_str, obj_attr_dict):
    """Register schema attributes to configure all instances of an object class.
       For instance: register_resource_schema_attributes('bsc', {'net.codec_list[]': schema.CODEC})
    """
    global _CONFIG_SCHEMA, _ALL_SCHEMA
    tmpdict = {}
    for key, val in obj_attr_dict.items():
        new_key = '%s.%s' % (obj_class_str, key)
        tmpdict[new_key] = val
    combine(_CONFIG_SCHEMA, tmpdict)
    _ALL_SCHEMA = None # reset _ALL_SCHEMA so it is re-generated next time it's requested.

def get_resources_schema():
    return _RESOURCES_SCHEMA;

def get_want_schema():
    global _WANT_SCHEMA
    if _WANT_SCHEMA is None:
        _WANT_SCHEMA = util.dict_add(
            dict([('%s[].times' % r, TIMES) for r in _RESOURCE_TYPES]),
            get_resources_schema())
    return _WANT_SCHEMA

def get_all_schema():
    global _ALL_SCHEMA
    if _ALL_SCHEMA is None:
        want_schema = get_want_schema()
        _ALL_SCHEMA = util.dict_add(
                        dict([('config.%s' % key, val) for key, val in _CONFIG_SCHEMA.items()]),
                        dict([('resources.%s' % key, val) for key, val in want_schema.items()]),
                        dict([('modifiers.%s' % key, val) for key, val in want_schema.items()]))
    return _ALL_SCHEMA

# vim: expandtab tabstop=4 shiftwidth=4
