import xml.etree.ElementTree as ET
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *


# Windows does not allow quotes in file names.
@skipIf(hostoslist=["windows"])
@skipIfRemote
class TestGdbRemoteLibrariesSvr4Support(gdbremote_testcase.GdbRemoteTestCaseBase):
    FEATURE_NAME = "qXfer:libraries-svr4:read"

    def setup_test(self):
        self.build()
        self.set_inferior_startup_launch()
        env = {}
        env[self.dylibPath] = self.getBuildDir()
        self.prep_debug_monitor_and_inferior(inferior_env=env)
        self.continue_process_and_wait_for_stop()

    def get_expected_libs(self):
        return ["libsvr4lib_a.so", 'libsvr4lib_b".so']

    def has_libraries_svr4_support(self):
        self.add_qSupported_packets()
        context = self.expect_gdbremote_sequence()
        self.assertIsNotNone(context)
        features = self.parse_qSupported_response(context)
        return self.FEATURE_NAME in features and features[self.FEATURE_NAME] == "+"

    def get_libraries_svr4_data(self):
        # Start up llgs and inferior, and check for libraries-svr4 support.
        if not self.has_libraries_svr4_support():
            self.skipTest("libraries-svr4 not supported")

        # Grab the libraries-svr4 data.
        self.reset_test_sequence()
        self.test_sequence.add_log_lines(
            [
                "read packet: $qXfer:libraries-svr4:read::0,ffff:#00",
                {
                    "direction": "send",
                    "regex": re.compile(
                        r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL
                    ),
                    "capture": {1: "response_type", 2: "content_raw"},
                },
            ],
            True,
        )

        context = self.expect_gdbremote_sequence()
        self.assertIsNotNone(context)

        # Ensure we end up with all libraries-svr4 data in one packet.
        self.assertEqual(context.get("response_type"), "l")

        # Decode binary data.
        content_raw = context.get("content_raw")
        self.assertIsNotNone(content_raw)
        return content_raw

    def get_libraries_svr4_xml(self):
        libraries_svr4 = self.get_libraries_svr4_data()
        xml_root = None
        try:
            xml_root = ET.fromstring(libraries_svr4)
        except xml.etree.ElementTree.ParseError:
            pass
        self.assertIsNotNone(xml_root, "Malformed libraries-svr4 XML")
        return xml_root

    def libraries_svr4_well_formed(self):
        xml_root = self.get_libraries_svr4_xml()
        self.assertEqual(xml_root.tag, "library-list-svr4")
        for child in xml_root:
            self.assertEqual(child.tag, "library")
            self.assertCountEqual(child.attrib.keys(), ["name", "lm", "l_addr", "l_ld"])

    def libraries_svr4_has_correct_load_addr(self):
        xml_root = self.get_libraries_svr4_xml()
        for child in xml_root:
            name = child.attrib.get("name")
            base_name = os.path.basename(name)
            if os.path.basename(name) not in self.get_expected_libs():
                continue
            load_addr = int(child.attrib.get("l_addr"), 16)
            self.reset_test_sequence()
            self.add_query_memory_region_packets(load_addr)
            context = self.expect_gdbremote_sequence()
            mem_region = self.parse_memory_region_packet(context)
            self.assertEqual(load_addr, int(mem_region.get("start", 0), 16))
            self.assertEqual(
                os.path.realpath(name), os.path.realpath(mem_region.get("name", ""))
            )

    def libraries_svr4_libs_present(self):
        xml_root = self.get_libraries_svr4_xml()
        libraries_svr4_names = []
        for child in xml_root:
            name = child.attrib.get("name")
            libraries_svr4_names.append(os.path.realpath(name))
        for lib in self.get_expected_libs():
            self.assertIn(
                os.path.realpath(self.getBuildDir() + "/" + lib), libraries_svr4_names
            )

    @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"])
    def test_supports_libraries_svr4(self):
        self.setup_test()
        self.assertTrue(self.has_libraries_svr4_support())

    @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"])
    @expectedFailureNetBSD
    def test_libraries_svr4_well_formed(self):
        self.setup_test()
        self.libraries_svr4_well_formed()

    @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"])
    @expectedFailureNetBSD
    def test_libraries_svr4_load_addr(self):
        self.setup_test()
        self.libraries_svr4_has_correct_load_addr()

    @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"])
    @expectedFailureNetBSD
    def test_libraries_svr4_libs_present(self):
        self.setup_test()
        self.libraries_svr4_libs_present()
