#!/usr/bin/env python3

"""Generate library/ssl_debug_helpers_generated.c

The code generated by this module includes debug helper functions that can not be
implemented by fixed codes.

"""

# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# 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 sys
import re
import os
import textwrap
import argparse
from mbedtls_dev import build_tree


def remove_c_comments(string):
    """
        Remove C style comments from input string
    """
    string_pattern = r"(?P<string>\".*?\"|\'.*?\')"
    comment_pattern = r"(?P<comment>/\*.*?\*/|//[^\r\n]*$)"
    pattern = re.compile(string_pattern + r'|' + comment_pattern,
                         re.MULTILINE | re.DOTALL)

    def replacer(match):
        if match.lastgroup == 'comment':
            return ""
        return match.group()
    return pattern.sub(replacer, string)


class CondDirectiveNotMatch(Exception):
    pass


def preprocess_c_source_code(source, *classes):
    """
        Simple preprocessor for C source code.

        Only processes condition directives without expanding them.
        Yield object according to the classes input. Most match firstly

        If the directive pair does not match , raise CondDirectiveNotMatch.

        Assume source code does not include comments and compile pass.

    """

    pattern = re.compile(r"^[ \t]*#[ \t]*" +
                         r"(?P<directive>(if[ \t]|ifndef[ \t]|ifdef[ \t]|else|endif))" +
                         r"[ \t]*(?P<param>(.*\\\n)*.*$)",
                         re.MULTILINE)
    stack = []

    def _yield_objects(s, d, p, st, end):
        """
            Output matched source piece
        """
        nonlocal stack
        start_line, end_line = '', ''
        if stack:
            start_line = '#{} {}'.format(d, p)
            if d == 'if':
                end_line = '#endif /* {} */'.format(p)
            elif d == 'ifdef':
                end_line = '#endif /* defined({}) */'.format(p)
            else:
                end_line = '#endif /* !defined({}) */'.format(p)
        has_instance = False
        for cls in classes:
            for instance in cls.extract(s, st, end):
                if has_instance is False:
                    has_instance = True
                    yield pair_start, start_line
                yield instance.span()[0], instance
        if has_instance:
            yield start, end_line

    for match in pattern.finditer(source):

        directive = match.groupdict()['directive'].strip()
        param = match.groupdict()['param']
        start, end = match.span()

        if directive in ('if', 'ifndef', 'ifdef'):
            stack.append((directive, param, start, end))
            continue

        if not stack:
            raise CondDirectiveNotMatch()

        pair_directive, pair_param, pair_start, pair_end = stack.pop()
        yield from _yield_objects(source,
                                  pair_directive,
                                  pair_param,
                                  pair_end,
                                  start)

        if directive == 'endif':
            continue

        if pair_directive == 'if':
            directive = 'if'
            param = "!( {} )".format(pair_param)
        elif pair_directive == 'ifdef':
            directive = 'ifndef'
            param = pair_param
        else:
            directive = 'ifdef'
            param = pair_param

        stack.append((directive, param, start, end))
    assert not stack, len(stack)


class EnumDefinition:
    """
        Generate helper functions around enumeration.

        Currently, it generate translation function from enum value to string.
        Enum definition looks like:
        [typedef] enum [prefix name] { [body] } [suffix name];

        Known limitation:
        - the '}' and ';' SHOULD NOT exist in different macro blocks. Like
        ```
        enum test {
            ....
        #if defined(A)
            ....
        };
        #else
            ....
        };
        #endif
        ```
    """

    @classmethod
    def extract(cls, source_code, start=0, end=-1):
        enum_pattern = re.compile(r'enum\s*(?P<prefix_name>\w*)\s*' +
                                  r'{\s*(?P<body>[^}]*)}' +
                                  r'\s*(?P<suffix_name>\w*)\s*;',
                                  re.MULTILINE | re.DOTALL)

        for match in enum_pattern.finditer(source_code, start, end):
            yield EnumDefinition(source_code,
                                 span=match.span(),
                                 group=match.groupdict())

    def __init__(self, source_code, span=None, group=None):
        assert isinstance(group, dict)
        prefix_name = group.get('prefix_name', None)
        suffix_name = group.get('suffix_name', None)
        body = group.get('body', None)
        assert prefix_name or suffix_name
        assert body
        assert span
        # If suffix_name exists, it is a typedef
        self._prototype = suffix_name if suffix_name else 'enum ' + prefix_name
        self._name = suffix_name if suffix_name else prefix_name
        self._body = body
        self._source = source_code
        self._span = span

    def __repr__(self):
        return 'Enum({},{})'.format(self._name, self._span)

    def __str__(self):
        return repr(self)

    def span(self):
        return self._span

    def generate_translation_function(self):
        """
            Generate function for translating value to string
        """
        translation_table = []

        for line in self._body.splitlines():

            if line.strip().startswith('#'):
                # Preprocess directive, keep it in table
                translation_table.append(line.strip())
                continue

            if not line.strip():
                continue

            for field in line.strip().split(','):
                if not field.strip():
                    continue
                member = field.strip().split()[0]
                translation_table.append(
                    '{space}[{member}] = "{member}",'.format(member=member,
                                                             space=' '*8)
                )

        body = textwrap.dedent('''\
            const char *{name}_str( {prototype} in )
            {{
                const char * in_to_str[]=
                {{
            {translation_table}
                }};

                if( in > ( sizeof( in_to_str )/sizeof( in_to_str[0]) - 1 ) ||
                    in_to_str[ in ] == NULL )
                {{
                    return "UNKNOWN_VALUE";
                }}
                return in_to_str[ in ];
            }}
                    ''')
        body = body.format(translation_table='\n'.join(translation_table),
                           name=self._name,
                           prototype=self._prototype)
        return body


class SignatureAlgorithmDefinition:
    """
        Generate helper functions for signature algorithms.

        It generates translation function from signature algorithm define to string.
        Signature algorithm definition looks like:
        #define MBEDTLS_TLS1_3_SIG_[ upper case signature algorithm ] [ value(hex) ]

        Known limitation:
        - the definitions SHOULD  exist in same macro blocks.
    """

    @classmethod
    def extract(cls, source_code, start=0, end=-1):
        sig_alg_pattern = re.compile(r'#define\s+(?P<name>MBEDTLS_TLS1_3_SIG_\w+)\s+' +
                                     r'(?P<value>0[xX][0-9a-fA-F]+)$',
                                     re.MULTILINE | re.DOTALL)
        matches = list(sig_alg_pattern.finditer(source_code, start, end))
        if matches:
            yield SignatureAlgorithmDefinition(source_code, definitions=matches)

    def __init__(self, source_code, definitions=None):
        if definitions is None:
            definitions = []
        assert isinstance(definitions, list) and definitions
        self._definitions = definitions
        self._source = source_code

    def __repr__(self):
        return 'SigAlgs({})'.format(self._definitions[0].span())

    def span(self):
        return self._definitions[0].span()

    def __str__(self):
        """
            Generate function for translating value to string
        """
        translation_table = []
        for m in self._definitions:
            name = m.groupdict()['name']
            return_val = name[len('MBEDTLS_TLS1_3_SIG_'):].lower()
            translation_table.append(
                '    case {}:\n        return "{}";'.format(name, return_val))

        body = textwrap.dedent('''\
            const char *mbedtls_ssl_sig_alg_to_str( uint16_t in )
            {{
                switch( in )
                {{
            {translation_table}
                }};

                return "UNKNOWN";
            }}''')
        body = body.format(translation_table='\n'.join(translation_table))
        return body


class NamedGroupDefinition:
    """
        Generate helper functions for named group

        It generates translation function from named group define to string.
        Named group definition looks like:
        #define MBEDTLS_SSL_IANA_TLS_GROUP_[ upper case named group ] [ value(hex) ]

        Known limitation:
        - the definitions SHOULD exist in same macro blocks.
    """

    @classmethod
    def extract(cls, source_code, start=0, end=-1):
        named_group_pattern = re.compile(r'#define\s+(?P<name>MBEDTLS_SSL_IANA_TLS_GROUP_\w+)\s+' +
                                         r'(?P<value>0[xX][0-9a-fA-F]+)$',
                                         re.MULTILINE | re.DOTALL)
        matches = list(named_group_pattern.finditer(source_code, start, end))
        if matches:
            yield NamedGroupDefinition(source_code, definitions=matches)

    def __init__(self, source_code, definitions=None):
        if definitions is None:
            definitions = []
        assert isinstance(definitions, list) and definitions
        self._definitions = definitions
        self._source = source_code

    def __repr__(self):
        return 'NamedGroup({})'.format(self._definitions[0].span())

    def span(self):
        return self._definitions[0].span()

    def __str__(self):
        """
            Generate function for translating value to string
        """
        translation_table = []
        for m in self._definitions:
            name = m.groupdict()['name']
            iana_name = name[len('MBEDTLS_SSL_IANA_TLS_GROUP_'):].lower()
            translation_table.append('    case {}:\n        return "{}";'.format(name, iana_name))

        body = textwrap.dedent('''\
            const char *mbedtls_ssl_named_group_to_str( uint16_t in )
            {{
                switch( in )
                {{
            {translation_table}
                }};

                return "UNKOWN";
            }}''')
        body = body.format(translation_table='\n'.join(translation_table))
        return body


OUTPUT_C_TEMPLATE = '''\
/* Automatically generated by generate_ssl_debug_helpers.py. DO NOT EDIT. */

/**
 * \\file ssl_debug_helpers_generated.c
 *
 * \\brief Automatically generated helper functions for debugging
 */
/*
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  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.
 */

#include "common.h"

#if defined(MBEDTLS_DEBUG_C)

#include "ssl_debug_helpers.h"

{functions}

#endif /* MBEDTLS_DEBUG_C */
/* End of automatically generated file. */

'''


def generate_ssl_debug_helpers(output_directory, mbedtls_root):
    """
        Generate functions of debug helps
    """
    mbedtls_root = os.path.abspath(
        mbedtls_root or build_tree.guess_mbedtls_root())
    with open(os.path.join(mbedtls_root, 'include/mbedtls/ssl.h')) as f:
        source_code = remove_c_comments(f.read())

    definitions = dict()
    for start, instance in preprocess_c_source_code(source_code,
                                                    EnumDefinition,
                                                    SignatureAlgorithmDefinition,
                                                    NamedGroupDefinition):
        if start in definitions:
            continue
        if isinstance(instance, EnumDefinition):
            definition = instance.generate_translation_function()
        else:
            definition = instance
        definitions[start] = definition

    function_definitions = [str(v) for _, v in sorted(definitions.items())]
    if output_directory == sys.stdout:
        sys.stdout.write(OUTPUT_C_TEMPLATE.format(
            functions='\n'.join(function_definitions)))
    else:
        with open(os.path.join(output_directory, 'ssl_debug_helpers_generated.c'), 'w') as f:
            f.write(OUTPUT_C_TEMPLATE.format(
                functions='\n'.join(function_definitions)))


def main():
    """
    Command line entry
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('--mbedtls-root', nargs='?', default=None,
                        help='root directory of mbedtls source code')
    parser.add_argument('output_directory', nargs='?',
                        default='library', help='source/header files location')

    args = parser.parse_args()

    generate_ssl_debug_helpers(args.output_directory, args.mbedtls_root)
    return 0


if __name__ == '__main__':
    sys.exit(main())
