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

# With picolibc, test_program_stderr_is_not_conflated_with_stdout fails
# because stdout & stderr are treated as the same.
# XFAIL: LIBCXX-PICOLIBC-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(__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",
            order="smart",
            params={},
        )

        self.config = lit.TestingConfig.TestingConfig.fromdefaults(self.litConfig)
        self.config.environment = dict(os.environ)
        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 TestProgramSucceeds(SetupConfigs):
    """
    Tests for libcxx.test.dsl.programSucceeds
    """

    def test_success(self):
        source = """
        int main(int, char**) { return 0; }
        """
        self.assertTrue(dsl.programSucceeds(self.config, source))

    def test_failure(self):
        source = """
        int main(int, char**) { return 1; }
        """
        self.assertFalse(dsl.programSucceeds(self.config, source))

    def test_compile_failure(self):
        source = """
        this does not compile
        """
        self.assertRaises(
            dsl.ConfigurationCompilationError,
            lambda: dsl.programSucceeds(self.config, source),
        )


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, ["forsurethisisnotanexistinglocale"])
        )

    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)
