"""Generate and run C code.
"""

# 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 os
import platform
import subprocess
import sys
import tempfile

def remove_file_if_exists(filename):
    """Remove the specified file, ignoring errors."""
    if not filename:
        return
    try:
        os.remove(filename)
    except OSError:
        pass

def create_c_file(file_label):
    """Create a temporary C file.

    * ``file_label``: a string that will be included in the file name.

    Return ```(c_file, c_name, exe_name)``` where ``c_file`` is a Python
    stream open for writing to the file, ``c_name`` is the name of the file
    and ``exe_name`` is the name of the executable that will be produced
    by compiling the file.
    """
    c_fd, c_name = tempfile.mkstemp(prefix='tmp-{}-'.format(file_label),
                                    suffix='.c')
    exe_suffix = '.exe' if platform.system() == 'Windows' else ''
    exe_name = c_name[:-2] + exe_suffix
    remove_file_if_exists(exe_name)
    c_file = os.fdopen(c_fd, 'w', encoding='ascii')
    return c_file, c_name, exe_name

def generate_c_printf_expressions(c_file, cast_to, printf_format, expressions):
    """Generate C instructions to print the value of ``expressions``.

    Write the code with ``c_file``'s ``write`` method.

    Each expression is cast to the type ``cast_to`` and printed with the
    printf format ``printf_format``.
    """
    for expr in expressions:
        c_file.write('    printf("{}\\n", ({}) {});\n'
                     .format(printf_format, cast_to, expr))

def generate_c_file(c_file,
                    caller, header,
                    main_generator):
    """Generate a temporary C source file.

    * ``c_file`` is an open stream on the C source file.
    * ``caller``: an informational string written in a comment at the top
      of the file.
    * ``header``: extra code to insert before any function in the generated
      C file.
    * ``main_generator``: a function called with ``c_file`` as its sole argument
      to generate the body of the ``main()`` function.
    """
    c_file.write('/* Generated by {} */'
                 .format(caller))
    c_file.write('''
#include <stdio.h>
''')
    c_file.write(header)
    c_file.write('''
int main(void)
{
''')
    main_generator(c_file)
    c_file.write('''    return 0;
}
''')

def get_c_expression_values(
        cast_to, printf_format,
        expressions,
        caller=__name__, file_label='',
        header='', include_path=None,
        keep_c=False,
): # pylint: disable=too-many-arguments, too-many-locals
    """Generate and run a program to print out numerical values for expressions.

    * ``cast_to``: a C type.
    * ``printf_format``: a printf format suitable for the type ``cast_to``.
    * ``header``: extra code to insert before any function in the generated
      C file.
    * ``expressions``: a list of C language expressions that have the type
      ``cast_to``.
    * ``include_path``: a list of directories containing header files.
    * ``keep_c``: if true, keep the temporary C file (presumably for debugging
      purposes).

    Use the C compiler specified by the ``CC`` environment variable, defaulting
    to ``cc``. If ``CC`` looks like MSVC, use its command line syntax,
    otherwise assume the compiler supports Unix traditional ``-I`` and ``-o``.

    Return the list of values of the ``expressions``.
    """
    if include_path is None:
        include_path = []
    c_name = None
    exe_name = None
    obj_name = None
    try:
        c_file, c_name, exe_name = create_c_file(file_label)
        generate_c_file(
            c_file, caller, header,
            lambda c_file: generate_c_printf_expressions(c_file,
                                                         cast_to, printf_format,
                                                         expressions)
        )
        c_file.close()
        cc = os.getenv('CC', 'cc')
        cmd = [cc]

        proc = subprocess.Popen(cmd,
                                stdout=subprocess.DEVNULL,
                                stderr=subprocess.PIPE,
                                universal_newlines=True)
        cc_is_msvc = 'Microsoft (R) C/C++ Optimizing Compiler' in \
                      proc.communicate()[1]

        cmd += ['-I' + dir for dir in include_path]
        if cc_is_msvc:
            # MSVC has deprecated using -o to specify the output file,
            # and produces an object file in the working directory by default.
            obj_name = exe_name[:-4] + '.obj'
            cmd += ['-Fe' + exe_name, '-Fo' + obj_name]
        else:
            cmd += ['-o' + exe_name]
        subprocess.check_call(cmd + [c_name])
        if keep_c:
            sys.stderr.write('List of {} tests kept at {}\n'
                             .format(caller, c_name))
        else:
            os.remove(c_name)
        output = subprocess.check_output([exe_name])
        return output.decode('ascii').strip().split('\n')
    finally:
        remove_file_if_exists(exe_name)
        remove_file_if_exists(obj_name)
