#
#    Copyright (c) 2022 Project CHIP Authors
#
#    Licensed under the Apache License, Version 2.0 (the 'License');
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an 'AS IS' BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.

import binascii
import re

'''Fixes certain value formats known to exist in YAML tests

Some of the YAML test files contains some values that has been crafted to avoid some limitations
of the original JavaScript parser and the C++ generated bits. This file contains functions to
changes and convert those YAML values them back to something agnostic.
'''


def try_apply_yaml_cpp_longlong_limitation_fix(value):
    '''Fix a known nasty hack in order that was used to work around compiler issue for C++.

    When -9223372036854775808 was provided compiler would give a warning saying it is not a valid
    way to write a long long in C++.
    '''
    if value == "-9223372036854775807LL - 1":
        value = -9223372036854775808
    return value


def try_apply_float_to_integer_fix(value):
    '''Fix math operations where values ends up beeing a float for integer types.

    For example one of the color control test configure the ColoremperatureMireds value to be:
        (ColorTempPhysicalMinMireds + ColorTempPhysicalMaxMireds)/2
    In this specific example it ends up as '32639.5', which is invalid.
    '''
    if isinstance(value, float):
        return int(value)
    return value


def try_apply_yaml_unrepresentable_integer_for_javascript_fixes(value):
    '''Fix up large integers that are represented within a string.

    JavaScript can not represent integers bigger than 9007199254740991. But some of the test may
    uses values that are bigger than this. The current way to workaround this limitation has
    been to write those numbers as strings by encapsulating them in "".
    Conversion happens on a best effort basis. For example, the type of value can be a string
    because a variable has been used, in which case, it would not convert to a proper int
    and we would fail at runtime.
    '''
    if type(value) is str:
        try:
            value = int(value)
        except:
            pass
    return value


def try_apply_yaml_float_written_as_strings(value):
    '''Fix up floats that are represented within a string.'''
    if type(value) is str:
        value = float(value)
    return value


def convert_yaml_octet_string_to_bytes(s: str) -> bytes:
    '''Convert YAML octet string body to bytes.

    This handles any c-style hex escapes (e.g. \x5a) and hex: prefix
    '''
    # Step 0: Check if this is already of type bytes
    if isinstance(s, bytes):
        return s

    # Step 1: handle explicit "hex:" prefix
    if s.startswith('hex:'):
        return binascii.unhexlify(s[4:])

    # Step 2: handle explicit "base64:" prefix
    if s.startswith('base64:'):
        return binascii.a2b_base64(s[7:])

    # Step 3: convert non-hex-prefixed to bytes
    # TODO(#23669): This does not properly support utf8 octet strings. We mimic
    # javascript codegen behavior. Behavior of javascript is:
    #   * Octet string character >= u+0200 errors out.
    #   * Any character greater than 0xFF has the upper bytes chopped off.
    as_bytes = [ord(c) for c in s]

    if any([value > 0x200 for value in as_bytes]):
        raise ValueError('Unsupported char in octet string %r' % as_bytes)
    accumulated_hex = ''.join([f"{(v & 0xFF):02x}" for v in as_bytes])
    return binascii.unhexlify(accumulated_hex)


def add_yaml_support_for_scientific_notation_without_dot(loader):
    regular_expression = re.compile(u'''^(?:
     [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
    |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
    |\\.[0-9_]+(?:[eE][-+][0-9]+)?
    |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*
    |[-+]?\\.(?:inf|Inf|INF)
    |\\.(?:nan|NaN|NAN))$''', re.X)

    loader.add_implicit_resolver(
        u'tag:yaml.org,2002:float',
        regular_expression,
        list(u'-+0123456789.'))


# This is a gross hack. The previous runner has a some internal states where an identity match one
# accessory. But this state may not exist in the runner (as in it prevent to have multiple node ids
# associated to a fabric...) so the 'nodeId' needs to be added back manually.
def try_update_yaml_node_id_test_runner_state(tests, config):
    default_identity = 'alpha'
    identities = {
        default_identity: None if 'nodeId' not in config else config['nodeId']}

    for test in tests:
        if not test.is_enabled:
            continue

        identity = test.identity

        if test.cluster == 'CommissionerCommands' or test.cluster == 'DelayCommands':
            if test.command == 'PairWithCode' or test.command == 'WaitForCommissionee':
                if test.responses_with_placeholders:
                    # It the test expects an error, we should not update the
                    # nodeId of the identity.
                    error = test.responses_with_placeholders[0].get('error')
                    if error:
                        continue

                for item in test.arguments_with_placeholders['values']:
                    if item['name'] == 'nodeId':
                        identities[identity] = item['value']
        elif identity is not None and identity in identities:
            node_id = identities[identity]
            test.node_id = node_id
        elif identity is None and default_identity in identities:
            node_id = identities[default_identity]
            test.node_id = node_id
