"""Bootstrap tests

Run these with `x test bootstrap`, or `python -m unittest src/bootstrap/bootstrap_test.py`."""

from __future__ import absolute_import, division, print_function
import os
import unittest
from unittest.mock import patch
import tempfile
import hashlib
import sys

from shutil import rmtree

# Allow running this from the top-level directory.
bootstrap_dir = os.path.dirname(os.path.abspath(__file__))
# For the import below, have Python search in src/bootstrap first.
sys.path.insert(0, bootstrap_dir)
import bootstrap  # noqa: E402
import configure  # noqa: E402


def serialize_and_parse(configure_args, bootstrap_args=None):
    from io import StringIO

    if bootstrap_args is None:
        bootstrap_args = bootstrap.FakeArgs()

    section_order, sections, targets = configure.parse_args(configure_args)
    buffer = StringIO()
    configure.write_config_toml(buffer, section_order, targets, sections)
    build = bootstrap.RustBuild(config_toml=buffer.getvalue(), args=bootstrap_args)

    try:
        import tomllib

        # Verify this is actually valid TOML.
        tomllib.loads(build.config_toml)
    except ImportError:
        print(
            "WARNING: skipping TOML validation, need at least python 3.11",
            file=sys.stderr,
        )
    return build


class VerifyTestCase(unittest.TestCase):
    """Test Case for verify"""

    def setUp(self):
        self.container = tempfile.mkdtemp()
        self.src = os.path.join(self.container, "src.txt")
        self.bad_src = os.path.join(self.container, "bad.txt")
        content = "Hello world"

        self.expected = hashlib.sha256(content.encode("utf-8")).hexdigest()

        with open(self.src, "w") as src:
            src.write(content)
        with open(self.bad_src, "w") as bad:
            bad.write("Hello!")

    def tearDown(self):
        rmtree(self.container)

    def test_valid_file(self):
        """Check if the sha256 sum of the given file is valid"""
        self.assertTrue(bootstrap.verify(self.src, self.expected, False))

    def test_invalid_file(self):
        """Should verify that the file is invalid"""
        self.assertFalse(bootstrap.verify(self.bad_src, self.expected, False))


class ProgramOutOfDate(unittest.TestCase):
    """Test if a program is out of date"""

    def setUp(self):
        self.container = tempfile.mkdtemp()
        os.mkdir(os.path.join(self.container, "stage0"))
        self.build = bootstrap.RustBuild()
        self.build.date = "2017-06-15"
        self.build.build_dir = self.container
        self.rustc_stamp_path = os.path.join(self.container, "stage0", ".rustc-stamp")
        self.key = self.build.date + str(None)

    def tearDown(self):
        rmtree(self.container)

    def test_stamp_path_does_not_exist(self):
        """Return True when the stamp file does not exist"""
        if os.path.exists(self.rustc_stamp_path):
            os.unlink(self.rustc_stamp_path)
        self.assertTrue(self.build.program_out_of_date(self.rustc_stamp_path, self.key))

    def test_dates_are_different(self):
        """Return True when the dates are different"""
        with open(self.rustc_stamp_path, "w") as rustc_stamp:
            rustc_stamp.write("2017-06-14None")
        self.assertTrue(self.build.program_out_of_date(self.rustc_stamp_path, self.key))

    def test_same_dates(self):
        """Return False both dates match"""
        with open(self.rustc_stamp_path, "w") as rustc_stamp:
            rustc_stamp.write("2017-06-15None")
        self.assertFalse(
            self.build.program_out_of_date(self.rustc_stamp_path, self.key)
        )


class ParseArgsInConfigure(unittest.TestCase):
    """Test if `parse_args` function in `configure.py` works properly"""

    @patch("configure.err")
    def test_unknown_args(self, err):
        # It should be print an error message if the argument doesn't start with '--'
        configure.parse_args(["enable-full-tools"])
        err.assert_called_with("Option 'enable-full-tools' is not recognized")
        err.reset_mock()
        # It should be print an error message if the argument is not recognized
        configure.parse_args(["--some-random-flag"])
        err.assert_called_with("Option '--some-random-flag' is not recognized")

    @patch("configure.err")
    def test_need_value_args(self, err):
        """It should print an error message if a required argument value is missing"""
        configure.parse_args(["--target"])
        err.assert_called_with("Option '--target' needs a value (--target=val)")

    @patch("configure.err")
    def test_option_checking(self, err):
        # Options should be checked even if `--enable-option-checking` is not passed
        configure.parse_args(["--target"])
        err.assert_called_with("Option '--target' needs a value (--target=val)")
        err.reset_mock()
        # Options should be checked if `--enable-option-checking` is passed
        configure.parse_args(["--enable-option-checking", "--target"])
        err.assert_called_with("Option '--target' needs a value (--target=val)")
        err.reset_mock()
        # Options should not be checked if `--disable-option-checking` is passed
        configure.parse_args(["--disable-option-checking", "--target"])
        err.assert_not_called()

    @patch("configure.parse_example_config", lambda known_args, _: known_args)
    def test_known_args(self):
        # It should contain known and correct arguments
        known_args = configure.parse_args(["--enable-full-tools"])
        self.assertTrue(known_args["full-tools"][0][1])
        known_args = configure.parse_args(["--disable-full-tools"])
        self.assertFalse(known_args["full-tools"][0][1])
        # It should contain known arguments and their values
        known_args = configure.parse_args(["--target=x86_64-unknown-linux-gnu"])
        self.assertEqual(known_args["target"][0][1], "x86_64-unknown-linux-gnu")
        known_args = configure.parse_args(["--target", "x86_64-unknown-linux-gnu"])
        self.assertEqual(known_args["target"][0][1], "x86_64-unknown-linux-gnu")


class GenerateAndParseConfig(unittest.TestCase):
    """Test that we can serialize and deserialize a bootstrap.toml file"""

    def test_no_args(self):
        build = serialize_and_parse([])
        self.assertEqual(build.get_toml("profile"), "dist")
        self.assertIsNone(build.get_toml("llvm.download-ci-llvm"))

    def test_set_section(self):
        build = serialize_and_parse(["--set", "llvm.download-ci-llvm"])
        self.assertEqual(build.get_toml("download-ci-llvm", section="llvm"), "true")

    def test_set_target(self):
        build = serialize_and_parse(["--set", "target.x86_64-unknown-linux-gnu.cc=gcc"])
        self.assertEqual(
            build.get_toml("cc", section="target.x86_64-unknown-linux-gnu"), "gcc"
        )

    def test_set_top_level(self):
        build = serialize_and_parse(["--set", "profile=compiler"])
        self.assertEqual(build.get_toml("profile"), "compiler")

    def test_set_codegen_backends(self):
        build = serialize_and_parse(["--set", "rust.codegen-backends=cranelift"])
        self.assertNotEqual(
            build.config_toml.find("codegen-backends = ['cranelift']"), -1
        )
        build = serialize_and_parse(["--set", "rust.codegen-backends=cranelift,llvm"])
        self.assertNotEqual(
            build.config_toml.find("codegen-backends = ['cranelift', 'llvm']"), -1
        )
        build = serialize_and_parse(["--enable-full-tools"])
        self.assertNotEqual(build.config_toml.find("codegen-backends = ['llvm']"), -1)


class GetTomlDottedKeys(unittest.TestCase):
    """Test that get_toml understands the dotted-table key syntax that a
    hand-written bootstrap.toml may use (e.g. `build.cargo = "..."`), and that
    it checks the table a key belongs to. See issue #156948."""

    def parse(self, config_toml):
        return bootstrap.RustBuild(config_toml=config_toml, args=bootstrap.FakeArgs())

    def test_dotted_key(self):
        build = self.parse('build.cargo = "/path/to/cargo"')
        self.assertEqual(build.get_toml("cargo", "build"), "/path/to/cargo")

    def test_dotted_key_matches_section_form(self):
        dotted = self.parse('build.cargo = "/path/to/cargo"')
        section = self.parse('[build]\ncargo = "/path/to/cargo"')
        self.assertEqual(
            dotted.get_toml("cargo", "build"), section.get_toml("cargo", "build")
        )

    def test_dotted_key_wrong_section(self):
        # A `cargo` key in some other table must not be picked up for `build`.
        build = self.parse('[foo]\ncargo = "false"')
        self.assertIsNone(build.get_toml("cargo", "build"))

    def test_program_config_requires_build_table(self):
        # A cargo/rustc key outside [build] must be ignored; program_config
        # falls back to the stage0 default path rather than the misplaced value.
        wrong = self.parse('[foo]\ncargo = "/wrong/cargo"')
        cargo_default = os.path.join(
            wrong.bin_root(), "bin", "cargo" + bootstrap.EXE_SUFFIX
        )
        self.assertEqual(wrong.cargo(), cargo_default)

        wrong_rustc = self.parse('[foo]\nrustc = "/wrong/rustc"')
        rustc_default = os.path.join(
            wrong_rustc.bin_root(), "bin", "rustc" + bootstrap.EXE_SUFFIX
        )
        self.assertEqual(wrong_rustc.rustc(), rustc_default)

        # A dotted key in the build table is honored.
        right = self.parse('build.cargo = "/path/to/cargo"')
        self.assertEqual(right.cargo(), "/path/to/cargo")

    def test_dotted_target_key(self):
        build = self.parse('target.x86_64-unknown-linux-gnu.cc = "gcc"')
        self.assertEqual(build.get_toml("cc", "target.x86_64-unknown-linux-gnu"), "gcc")

    def test_dotted_key_inside_section(self):
        # A dotted key nested under a `[section]` header composes with that
        # section's name; it is equivalent to the fully top-level dotted form.
        nested = self.parse('[target]\nx86_64-unknown-linux-gnu.cc = "gcc"')
        self.assertEqual(
            nested.get_toml("cc", "target.x86_64-unknown-linux-gnu"), "gcc"
        )
        top_level = self.parse('target.x86_64-unknown-linux-gnu.cc = "gcc"')
        self.assertEqual(
            nested.get_toml("cc", "target.x86_64-unknown-linux-gnu"),
            top_level.get_toml("cc", "target.x86_64-unknown-linux-gnu"),
        )

    def test_dotted_prefix_does_not_alias_other_section(self):
        # `build.cargo` inside `[foo]` is `foo.build.cargo`, not the top-level
        # `[build]` table, so it must not be returned for section "build".
        build = self.parse('[foo]\nbuild.cargo = "false"')
        self.assertIsNone(build.get_toml("cargo", "build"))


class BuildBootstrap(unittest.TestCase):
    """Test that we generate the appropriate arguments when building bootstrap"""

    def build_args(self, configure_args=None, args=None, env=None):
        if configure_args is None:
            configure_args = []
        if args is None:
            args = []
        if env is None:
            env = {}

        # This test ends up invoking build_bootstrap_cmd, which searches for
        # the Cargo binary and errors out if it cannot be found. This is not a
        # problem in most cases, but there is a scenario where it would cause
        # the test to fail.
        #
        # When a custom local Cargo is configured in bootstrap.toml (with the
        # build.cargo setting), no Cargo is downloaded to any location known by
        # bootstrap, and bootstrap relies on that setting to find it.
        #
        # In this test though we are not using the bootstrap.toml of the caller:
        # we are generating a blank one instead. If we don't set build.cargo in
        # it, the test will have no way to find Cargo, failing the test.
        cargo_bin = os.environ.get("BOOTSTRAP_TEST_CARGO_BIN")
        if cargo_bin is not None:
            configure_args += ["--set", "build.cargo=" + cargo_bin]
        rustc_bin = os.environ.get("BOOTSTRAP_TEST_RUSTC_BIN")
        if rustc_bin is not None:
            configure_args += ["--set", "build.rustc=" + rustc_bin]

        env = env.copy()
        env["PATH"] = os.environ["PATH"]

        parsed = bootstrap.parse_args(args)
        build = serialize_and_parse(configure_args, parsed)
        # Make these optional so that `python -m unittest` works when run manually.
        build_dir = os.environ.get("BUILD_DIR")
        if build_dir is not None:
            build.build_dir = build_dir
        build_platform = os.environ.get("BUILD_PLATFORM")
        if build_platform is not None:
            build.build = build_platform
        return build.build_bootstrap_cmd(env), env

    def test_cargoflags(self):
        args, _ = self.build_args(env={"CARGOFLAGS": "--timings"})
        self.assertTrue("--timings" in args)

    def test_warnings(self):
        for toml_warnings in ["false", "true", None]:
            configure_args = []
            if toml_warnings is not None:
                configure_args = ["--set", "rust.deny-warnings=" + toml_warnings]

            args, env = self.build_args(configure_args, args=["--warnings=warn"])
            self.assertFalse("CARGO_BUILD_WARNINGS" in env)

            args, env = self.build_args(configure_args, args=["--warnings=deny"])
            self.assertEqual("deny", env["CARGO_BUILD_WARNINGS"])
