#===----------------------------------------------------------------------===##
#
# 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
#
#===----------------------------------------------------------------------===##

# XFAIL: LIBCXX-WINDOWS-FIXME

# Note: We prepend arguments with 'x' to avoid thinking there are too few
#       arguments in case an argument is an empty string.
# RUN: %{python} %s x%S x%T x%{substitutions}

import base64
import copy
import os
import pickle
import platform
import subprocess
import sys
import unittest
from os.path import dirname

# Allow importing 'lit' and the 'libcxx' module. Make sure we put the lit
# path first so we don't find any system-installed version.
monorepoRoot = dirname(dirname(dirname(dirname(dirname(dirname(__file__))))))
sys.path = [os.path.join(monorepoRoot, 'libcxx', 'utils'),
            os.path.join(monorepoRoot, 'llvm', 'utils', 'lit')] + sys.path
import libcxx.test.dsl as dsl
import lit.LitConfig
import lit.util

# Steal some parameters from the config running this test so that we can
# bootstrap our own TestingConfig.
args = list(map(lambda s: s[1:], sys.argv[1:8])) # Remove the leading 'x'
SOURCE_ROOT, EXEC_PATH, SUBSTITUTIONS = args
sys.argv[1:8] = []

# Decode the substitutions.
SUBSTITUTIONS = pickle.loads(base64.b64decode(SUBSTITUTIONS))
for s, sub in SUBSTITUTIONS:
    print("Substitution '{}' is '{}'".format(s, sub))

class SetupConfigs(unittest.TestCase):
    """
    Base class for the tests below -- it creates a fake TestingConfig.
    """
    def setUp(self):
        """
        Create a fake TestingConfig that can be populated however we wish for
        the purpose of running unit tests below. We pre-populate it with the
        minimum required substitutions.
        """
        self.litConfig = lit.LitConfig.LitConfig(
            progname='lit',
            path=[],
            quiet=False,
            useValgrind=False,
            valgrindLeakCheck=False,
            valgrindArgs=[],
            noExecute=False,
            debug=False,
            isWindows=platform.system() == 'Windows',
            params={})

        self.config = lit.TestingConfig.TestingConfig.fromdefaults(self.litConfig)
        self.config.test_source_root = SOURCE_ROOT
        self.config.test_exec_root = EXEC_PATH
        self.config.recursiveExpansionLimit = 10
        self.config.substitutions = copy.deepcopy(SUBSTITUTIONS)

    def getSubstitution(self, substitution):
        """
        Return a given substitution from the TestingConfig. It is an error if
        there is no such substitution.
        """
        found = [x for (s, x) in self.config.substitutions if s == substitution]
        assert len(found) == 1
        return found[0]


def findIndex(list, pred):
    """Finds the index of the first element satisfying 'pred' in a list, or
       'len(list)' if there is no such element."""
    index = 0
    for x in list:
        if pred(x):
            break
        else:
            index += 1
    return index


class TestHasCompileFlag(SetupConfigs):
    """
    Tests for libcxx.test.dsl.hasCompileFlag
    """
    def test_no_flag_should_work(self):
        self.assertTrue(dsl.hasCompileFlag(self.config, ''))

    def test_flag_exists(self):
        self.assertTrue(dsl.hasCompileFlag(self.config, '-O1'))

    def test_nonexistent_flag(self):
        self.assertFalse(dsl.hasCompileFlag(self.config, '-this_is_not_a_flag_any_compiler_has'))

    def test_multiple_flags(self):
        self.assertTrue(dsl.hasCompileFlag(self.config, '-O1 -Dhello'))


class TestSourceBuilds(SetupConfigs):
    """
    Tests for libcxx.test.dsl.sourceBuilds
    """
    def test_valid_program_builds(self):
        source = """int main(int, char**) { return 0; }"""
        self.assertTrue(dsl.sourceBuilds(self.config, source))

    def test_compilation_error_fails(self):
        source = """int main(int, char**) { this does not compile }"""
        self.assertFalse(dsl.sourceBuilds(self.config, source))

    def test_link_error_fails(self):
        source = """extern void this_isnt_defined_anywhere();
                    int main(int, char**) { this_isnt_defined_anywhere(); return 0; }"""
        self.assertFalse(dsl.sourceBuilds(self.config, source))


class TestProgramOutput(SetupConfigs):
    """
    Tests for libcxx.test.dsl.programOutput
    """
    def test_valid_program_returns_output(self):
        source = """
        #include <cstdio>
        int main(int, char**) { std::printf("FOOBAR"); return 0; }
        """
        self.assertEqual(dsl.programOutput(self.config, source), "FOOBAR")

    def test_valid_program_returns_output_newline_handling(self):
        source = """
        #include <cstdio>
        int main(int, char**) { std::printf("FOOBAR\\n"); return 0; }
        """
        self.assertEqual(dsl.programOutput(self.config, source), "FOOBAR\n")

    def test_valid_program_returns_no_output(self):
        source = """
        int main(int, char**) { return 0; }
        """
        self.assertEqual(dsl.programOutput(self.config, source), "")

    def test_program_that_fails_to_run_raises_runtime_error(self):
        # The program compiles, but exits with an error
        source = """
        int main(int, char**) { return 1; }
        """
        self.assertRaises(dsl.ConfigurationRuntimeError, lambda: dsl.programOutput(self.config, source))

    def test_program_that_fails_to_compile_raises_compilation_error(self):
        # The program doesn't compile
        source = """
        int main(int, char**) { this doesnt compile }
        """
        self.assertRaises(dsl.ConfigurationCompilationError, lambda: dsl.programOutput(self.config, source))

    def test_pass_arguments_to_program(self):
        source = """
        #include <cassert>
        #include <string>
        int main(int argc, char** argv) {
            assert(argc == 3);
            assert(argv[1] == std::string("first-argument"));
            assert(argv[2] == std::string("second-argument"));
            return 0;
        }
        """
        args = ["first-argument", "second-argument"]
        self.assertEqual(dsl.programOutput(self.config, source, args=args), "")

    def test_caching_is_not_too_aggressive(self):
        # Run a program, then change the substitutions and run it again.
        # Make sure the program is run the second time and the right result
        # is given, to ensure we're not incorrectly caching the result of the
        # first program run.
        source = """
        #include <cstdio>
        int main(int, char**) {
            std::printf("MACRO=%u\\n", MACRO);
            return 0;
        }
        """
        compileFlagsIndex = findIndex(self.config.substitutions, lambda x: x[0] == '%{compile_flags}')
        compileFlags = self.config.substitutions[compileFlagsIndex][1]

        self.config.substitutions[compileFlagsIndex] = ('%{compile_flags}',  compileFlags + ' -DMACRO=1')
        output1 = dsl.programOutput(self.config, source)
        self.assertEqual(output1, "MACRO=1\n")

        self.config.substitutions[compileFlagsIndex] = ('%{compile_flags}',  compileFlags + ' -DMACRO=2')
        output2 = dsl.programOutput(self.config, source)
        self.assertEqual(output2, "MACRO=2\n")

    def test_program_stderr_is_not_conflated_with_stdout(self):
        # Run a program that produces stdout output and stderr output too, making
        # sure the stderr output does not pollute the stdout output.
        source = """
        #include <cstdio>
        int main(int, char**) {
            std::fprintf(stdout, "STDOUT-OUTPUT");
            std::fprintf(stderr, "STDERR-OUTPUT");
            return 0;
        }
        """
        self.assertEqual(dsl.programOutput(self.config, source), "STDOUT-OUTPUT")


class TestHasLocale(SetupConfigs):
    """
    Tests for libcxx.test.dsl.hasLocale
    """
    def test_doesnt_explode(self):
        # It's really hard to test that a system has a given locale, so at least
        # make sure we don't explode when we try to check it.
        try:
            dsl.hasAnyLocale(self.config, ['en_US.UTF-8'])
        except subprocess.CalledProcessError:
            self.fail("checking for hasLocale should not explode")

    def test_nonexistent_locale(self):
        self.assertFalse(dsl.hasAnyLocale(self.config, ['for_sure_this_is_not_an_existing_locale']))

    def test_localization_program_doesnt_compile(self):
        compilerIndex = findIndex(self.config.substitutions, lambda x: x[0] == '%{cxx}')
        self.config.substitutions[compilerIndex] = ('%{cxx}', 'this-is-certainly-not-a-valid-compiler!!')
        self.assertRaises(dsl.ConfigurationCompilationError, lambda: dsl.hasAnyLocale(self.config, ['en_US.UTF-8']))


class TestCompilerMacros(SetupConfigs):
    """
    Tests for libcxx.test.dsl.compilerMacros
    """
    def test_basic(self):
        macros = dsl.compilerMacros(self.config)
        self.assertIsInstance(macros, dict)
        self.assertGreater(len(macros), 0)
        for (k, v) in macros.items():
            self.assertIsInstance(k, str)
            self.assertIsInstance(v, str)

    def test_no_flag(self):
        macros = dsl.compilerMacros(self.config)
        self.assertIn('__cplusplus', macros.keys())

    def test_empty_flag(self):
        macros = dsl.compilerMacros(self.config, '')
        self.assertIn('__cplusplus', macros.keys())

    def test_with_flag(self):
        macros = dsl.compilerMacros(self.config, '-DFOO=3')
        self.assertIn('__cplusplus', macros.keys())
        self.assertEqual(macros['FOO'], '3')

    def test_with_flags(self):
        macros = dsl.compilerMacros(self.config, '-DFOO=3 -DBAR=hello')
        self.assertIn('__cplusplus', macros.keys())
        self.assertEqual(macros['FOO'], '3')
        self.assertEqual(macros['BAR'], 'hello')


class TestFeatureTestMacros(SetupConfigs):
    """
    Tests for libcxx.test.dsl.featureTestMacros
    """
    def test_basic(self):
        macros = dsl.featureTestMacros(self.config)
        self.assertIsInstance(macros, dict)
        self.assertGreater(len(macros), 0)
        for (k, v) in macros.items():
            self.assertIsInstance(k, str)
            self.assertIsInstance(v, int)


class TestFeature(SetupConfigs):
    """
    Tests for libcxx.test.dsl.Feature
    """
    def test_trivial(self):
        feature = dsl.Feature(name='name')
        origSubstitutions = copy.deepcopy(self.config.substitutions)
        actions = feature.getActions(self.config)
        self.assertTrue(len(actions) == 1)
        for a in actions:
            a.applyTo(self.config)
        self.assertEqual(origSubstitutions, self.config.substitutions)
        self.assertIn('name', self.config.available_features)

    def test_name_can_be_a_callable(self):
        feature = dsl.Feature(name=lambda cfg: 'name')
        for a in feature.getActions(self.config):
            a.applyTo(self.config)
        self.assertIn('name', self.config.available_features)

    def test_name_is_not_a_string_1(self):
        feature = dsl.Feature(name=None)
        self.assertRaises(ValueError, lambda: feature.getActions(self.config))
        self.assertRaises(ValueError, lambda: feature.pretty(self.config))

    def test_name_is_not_a_string_2(self):
        feature = dsl.Feature(name=lambda cfg: None)
        self.assertRaises(ValueError, lambda: feature.getActions(self.config))
        self.assertRaises(ValueError, lambda: feature.pretty(self.config))

    def test_adding_action(self):
        feature = dsl.Feature(name='name', actions=[dsl.AddCompileFlag('-std=c++03')])
        origLinkFlags = copy.deepcopy(self.getSubstitution('%{link_flags}'))
        for a in feature.getActions(self.config):
            a.applyTo(self.config)
        self.assertIn('name', self.config.available_features)
        self.assertIn('-std=c++03', self.getSubstitution('%{compile_flags}'))
        self.assertEqual(origLinkFlags, self.getSubstitution('%{link_flags}'))

    def test_actions_can_be_a_callable(self):
        feature = dsl.Feature(name='name',
                              actions=lambda cfg: (
                                self.assertIs(self.config, cfg),
                                [dsl.AddCompileFlag('-std=c++03')]
                              )[1])
        for a in feature.getActions(self.config):
            a.applyTo(self.config)
        self.assertIn('-std=c++03', self.getSubstitution('%{compile_flags}'))

    def test_unsupported_feature(self):
        feature = dsl.Feature(name='name', when=lambda _: False)
        self.assertEqual(feature.getActions(self.config), [])

    def test_is_supported_gets_passed_the_config(self):
        feature = dsl.Feature(name='name', when=lambda cfg: (self.assertIs(self.config, cfg), True)[1])
        self.assertEqual(len(feature.getActions(self.config)), 1)


def _throw():
    raise ValueError()

class TestParameter(SetupConfigs):
    """
    Tests for libcxx.test.dsl.Parameter
    """
    def test_empty_name_should_blow_up(self):
        self.assertRaises(ValueError, lambda: dsl.Parameter(name='', choices=['c++03'], type=str, help='', actions=lambda _: []))

    def test_empty_choices_should_blow_up(self):
        self.assertRaises(ValueError, lambda: dsl.Parameter(name='std', choices=[], type=str, help='', actions=lambda _: []))

    def test_no_choices_is_ok(self):
        param = dsl.Parameter(name='triple', type=str, help='', actions=lambda _: [])
        self.assertEqual(param.name, 'triple')

    def test_name_is_set_correctly(self):
        param = dsl.Parameter(name='std', choices=['c++03'], type=str, help='', actions=lambda _: [])
        self.assertEqual(param.name, 'std')

    def test_no_value_provided_and_no_default_value(self):
        param = dsl.Parameter(name='std', choices=['c++03'], type=str, help='', actions=lambda _: [])
        self.assertRaises(ValueError, lambda: param.getActions(self.config, self.litConfig.params))

    def test_no_value_provided_and_default_value(self):
        param = dsl.Parameter(name='std', choices=['c++03'], type=str, help='', default='c++03',
                              actions=lambda std: [dsl.AddFeature(std)])
        for a in param.getActions(self.config, self.litConfig.params):
            a.applyTo(self.config)
        self.assertIn('c++03', self.config.available_features)

    def test_value_provided_on_command_line_and_no_default_value(self):
        self.litConfig.params['std'] = 'c++03'
        param = dsl.Parameter(name='std', choices=['c++03'], type=str, help='',
                              actions=lambda std: [dsl.AddFeature(std)])
        for a in param.getActions(self.config, self.litConfig.params):
            a.applyTo(self.config)
        self.assertIn('c++03', self.config.available_features)

    def test_value_provided_on_command_line_and_default_value(self):
        """The value provided on the command line should override the default value"""
        self.litConfig.params['std'] = 'c++11'
        param = dsl.Parameter(name='std', choices=['c++03', 'c++11'], type=str, default='c++03', help='',
                              actions=lambda std: [dsl.AddFeature(std)])
        for a in param.getActions(self.config, self.litConfig.params):
            a.applyTo(self.config)
        self.assertIn('c++11', self.config.available_features)
        self.assertNotIn('c++03', self.config.available_features)

    def test_value_provided_in_config_and_default_value(self):
        """The value provided in the config should override the default value"""
        self.config.std ='c++11'
        param = dsl.Parameter(name='std', choices=['c++03', 'c++11'], type=str, default='c++03', help='',
                              actions=lambda std: [dsl.AddFeature(std)])
        for a in param.getActions(self.config, self.litConfig.params):
            a.applyTo(self.config)
        self.assertIn('c++11', self.config.available_features)
        self.assertNotIn('c++03', self.config.available_features)

    def test_value_provided_in_config_and_on_command_line(self):
        """The value on the command line should override the one in the config"""
        self.config.std = 'c++11'
        self.litConfig.params['std'] = 'c++03'
        param = dsl.Parameter(name='std', choices=['c++03', 'c++11'], type=str, help='',
                              actions=lambda std: [dsl.AddFeature(std)])
        for a in param.getActions(self.config, self.litConfig.params):
            a.applyTo(self.config)
        self.assertIn('c++03', self.config.available_features)
        self.assertNotIn('c++11', self.config.available_features)

    def test_no_actions(self):
        self.litConfig.params['std'] = 'c++03'
        param = dsl.Parameter(name='std', choices=['c++03'], type=str, help='',
                              actions=lambda _: [])
        actions = param.getActions(self.config, self.litConfig.params)
        self.assertEqual(actions, [])

    def test_boolean_value_parsed_from_trueish_string_parameter(self):
        self.litConfig.params['enable_exceptions'] = "True"
        param = dsl.Parameter(name='enable_exceptions', choices=[True, False], type=bool, help='',
                              actions=lambda exceptions: [] if exceptions else _throw())
        self.assertEqual(param.getActions(self.config, self.litConfig.params), [])

    def test_boolean_value_from_true_boolean_parameter(self):
        self.litConfig.params['enable_exceptions'] = True
        param = dsl.Parameter(name='enable_exceptions', choices=[True, False], type=bool, help='',
                              actions=lambda exceptions: [] if exceptions else _throw())
        self.assertEqual(param.getActions(self.config, self.litConfig.params), [])

    def test_boolean_value_parsed_from_falseish_string_parameter(self):
        self.litConfig.params['enable_exceptions'] = "False"
        param = dsl.Parameter(name='enable_exceptions', choices=[True, False], type=bool, help='',
                              actions=lambda exceptions: [] if exceptions else [dsl.AddFeature("-fno-exceptions")])
        for a in param.getActions(self.config, self.litConfig.params):
            a.applyTo(self.config)
        self.assertIn('-fno-exceptions', self.config.available_features)

    def test_boolean_value_from_false_boolean_parameter(self):
        self.litConfig.params['enable_exceptions'] = False
        param = dsl.Parameter(name='enable_exceptions', choices=[True, False], type=bool, help='',
                              actions=lambda exceptions: [] if exceptions else [dsl.AddFeature("-fno-exceptions")])
        for a in param.getActions(self.config, self.litConfig.params):
            a.applyTo(self.config)
        self.assertIn('-fno-exceptions', self.config.available_features)

    def test_list_parsed_from_comma_delimited_string_empty(self):
        self.litConfig.params['additional_features'] = ""
        param = dsl.Parameter(name='additional_features', type=list, help='', actions=lambda f: f)
        self.assertEqual(param.getActions(self.config, self.litConfig.params), [])

    def test_list_parsed_from_comma_delimited_string_1(self):
        self.litConfig.params['additional_features'] = "feature1"
        param = dsl.Parameter(name='additional_features', type=list, help='', actions=lambda f: f)
        self.assertEqual(param.getActions(self.config, self.litConfig.params), ['feature1'])

    def test_list_parsed_from_comma_delimited_string_2(self):
        self.litConfig.params['additional_features'] = "feature1,feature2"
        param = dsl.Parameter(name='additional_features', type=list, help='', actions=lambda f: f)
        self.assertEqual(param.getActions(self.config, self.litConfig.params), ['feature1', 'feature2'])

    def test_list_parsed_from_comma_delimited_string_3(self):
        self.litConfig.params['additional_features'] = "feature1,feature2, feature3"
        param = dsl.Parameter(name='additional_features', type=list, help='', actions=lambda f: f)
        self.assertEqual(param.getActions(self.config, self.litConfig.params), ['feature1', 'feature2', 'feature3'])


if __name__ == '__main__':
    unittest.main(verbosity=2)
