# DExTer : Debugging Experience Tester
# ~~~~~~   ~         ~~         ~   ~~
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""Deals with the processing execution of shell or batch build scripts."""

import os
import subprocess
import unittest

from dex.dextIR import BuilderIR
from dex.utils import Timer
from dex.utils.Exceptions import BuildScriptException


def _quotify(text):
    if '"' in text or ' ' not in text:
        return text
    return '"{}"'.format(text)


def _get_script_environment(source_files, compiler_options,
                            linker_options, executable_file):

    source_files = [_quotify(f) for f in source_files]
    object_files = [
        _quotify('{}.o'.format(os.path.basename(f))) for f in source_files
    ]
    source_indexes = ['{:02d}'.format(i + 1) for i in range(len(source_files))]

    env_variables = {}
    env_variables['SOURCE_INDEXES'] = ' '.join(source_indexes)
    env_variables['SOURCE_FILES'] = ' '.join(source_files)
    env_variables['OBJECT_FILES'] = ' '.join(object_files)
    env_variables['LINKER_OPTIONS'] = linker_options

    for i, _ in enumerate(source_files):
        index = source_indexes[i]
        env_variables['SOURCE_FILE_{}'.format(index)] = source_files[i]
        env_variables['OBJECT_FILE_{}'.format(index)] = object_files[i]
        env_variables['COMPILER_OPTIONS_{}'.format(index)] = compiler_options[i]

    env_variables['EXECUTABLE_FILE'] = executable_file

    return env_variables


def run_external_build_script(context, script_path, source_files,
                              compiler_options, linker_options,
                              executable_file):
    """Build an executable using a builder script.

    The executable is saved to `context.working_directory.path`.

    Returns:
        ( stdout (str), stderr (str), builder (BuilderIR) )
    """

    builderIR = BuilderIR(
        name=context.options.builder,
        cflags=compiler_options,
        ldflags=linker_options,
    )
    assert len(source_files) == len(compiler_options), (source_files,
                                                        compiler_options)

    script_environ = _get_script_environment(source_files, compiler_options,
                                             linker_options, executable_file)
    env = dict(os.environ)
    env.update(script_environ)
    try:
        with Timer('running build script'):
            process = subprocess.Popen(
                [script_path],
                cwd=context.working_directory.path,
                env=env,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE)
            out, err = process.communicate()
            returncode = process.returncode
        out = out.decode('utf-8')
        err = err.decode('utf-8')
        if returncode != 0:
            raise BuildScriptException(
                '{}: failed with returncode {}.\nstdout:\n{}\n\nstderr:\n{}\n'.
                format(script_path, returncode, out, err),
                script_error=err)
        return out, err, builderIR
    except OSError as e:
        raise BuildScriptException('{}: {}'.format(e.strerror, script_path))


class TestBuilder(unittest.TestCase):
    def test_get_script_environment(self):
        source_files = ['a.a', 'b.b']
        compiler_options = ['-option1 value1', '-option2 value2']
        linker_options = '-optionX valueX'
        executable_file = 'exe.exe'
        env = _get_script_environment(source_files, compiler_options,
                                      linker_options, executable_file)

        assert env['SOURCE_FILES'] == 'a.a b.b'
        assert env['OBJECT_FILES'] == 'a.a.o b.b.o'

        assert env['SOURCE_INDEXES'] == '01 02'
        assert env['LINKER_OPTIONS'] == '-optionX valueX'

        assert env['SOURCE_FILE_01'] == 'a.a'
        assert env['SOURCE_FILE_02'] == 'b.b'

        assert env['OBJECT_FILE_01'] == 'a.a.o'
        assert env['OBJECT_FILE_02'] == 'b.b.o'

        assert env['EXECUTABLE_FILE'] == 'exe.exe'

        assert env['COMPILER_OPTIONS_01'] == '-option1 value1'
        assert env['COMPILER_OPTIONS_02'] == '-option2 value2'
