import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):
    """Test QSaveRegisterState/QRestoreRegisterState support."""

    def grp_register_save_restore_works(self, with_suffix):
        # Start up the process, use thread suffix, grab main thread id.
        inferior_args = ["message:main entered", "sleep:5"]
        procs = self.prep_debug_monitor_and_inferior(inferior_args=inferior_args)

        self.add_process_info_collection_packets()
        self.add_register_info_collection_packets()
        if with_suffix:
            self.add_thread_suffix_request_packets()
        self.add_threadinfo_collection_packets()

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

        # Gather process info.
        process_info = self.parse_process_info_response(context)
        endian = process_info.get("endian")
        self.assertIsNotNone(endian)

        # Gather register info.
        reg_infos = self.parse_register_info_packets(context)
        self.assertIsNotNone(reg_infos)
        self.add_lldb_register_index(reg_infos)

        # Pull out the register infos that we think we can bit flip
        # successfully.
        gpr_reg_infos = [
            reg_info
            for reg_info in reg_infos
            if self.is_bit_flippable_register(reg_info)
        ]
        self.assertGreater(len(gpr_reg_infos), 0)

        # Gather thread info.
        if with_suffix:
            threads = self.parse_threadinfo_packets(context)
            self.assertIsNotNone(threads)
            thread_id = threads[0]
            self.assertIsNotNone(thread_id)
            self.trace("Running on thread: 0x{:x}".format(thread_id))
        else:
            thread_id = None

        # Save register state.
        self.reset_test_sequence()
        self.add_QSaveRegisterState_packets(thread_id)

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

        (success, state_id) = self.parse_QSaveRegisterState_response(context)
        self.assertTrue(success)
        self.assertIsNotNone(state_id)
        self.trace("saved register state id: {}".format(state_id))

        # Remember initial register values.
        initial_reg_values = self.read_register_values(
            gpr_reg_infos, endian, thread_id=thread_id
        )
        self.trace("initial_reg_values: {}".format(initial_reg_values))

        # Flip gpr register values.
        (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(
            gpr_reg_infos, endian, thread_id=thread_id
        )
        self.trace(
            "successful writes: {}, failed writes: {}".format(
                successful_writes, failed_writes
            )
        )
        self.assertGreater(successful_writes, 0)

        flipped_reg_values = self.read_register_values(
            gpr_reg_infos, endian, thread_id=thread_id
        )
        self.trace("flipped_reg_values: {}".format(flipped_reg_values))

        # Restore register values.
        self.reset_test_sequence()
        self.add_QRestoreRegisterState_packets(state_id, thread_id)

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

        # Verify registers match initial register values.
        final_reg_values = self.read_register_values(
            gpr_reg_infos, endian, thread_id=thread_id
        )
        self.trace("final_reg_values: {}".format(final_reg_values))
        self.assertIsNotNone(final_reg_values)
        self.assertEqual(final_reg_values, initial_reg_values)

    def test_grp_register_save_restore_works_with_suffix(self):
        USE_THREAD_SUFFIX = True
        self.build()
        self.set_inferior_startup_launch()
        self.grp_register_save_restore_works(USE_THREAD_SUFFIX)

    def test_grp_register_save_restore_works_no_suffix(self):
        USE_THREAD_SUFFIX = False
        self.build()
        self.set_inferior_startup_launch()
        self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
