"""
Test that the batched breakpoint step-over optimization activates when
multiple threads hit the same breakpoint. Verifies that the optimization
reduces breakpoint toggle operations compared to stepping one at a time.
"""

import os
import re

from lldbsuite.test.decorators import *
from lldbsuite.test.concurrent_base import ConcurrentEventsBase
from lldbsuite.test.lldbtest import TestBase


@skipIfTargetDoesNotSupportThreads()
@skipIfWindows
class ConcurrentBatchedBreakpointStepOver(ConcurrentEventsBase):
    @skipIf(triple="^mips")
    @skipIf(archs=["aarch64"])
    def test(self):
        """Test that batched breakpoint step-over reduces breakpoint
        toggle operations when multiple threads hit the same breakpoint."""
        self.build()

        num_threads = 10

        # Enable logging to capture optimization messages and GDB packets.
        lldb_logfile = self.getBuildArtifact("lldb-log.txt")
        self.runCmd("log enable lldb step break -f {}".format(lldb_logfile))

        gdb_logfile = self.getBuildArtifact("gdb-remote-log.txt")
        self.runCmd("log enable gdb-remote packets -f {}".format(gdb_logfile))

        # Run with breakpoint threads.
        self.do_thread_actions(num_breakpoint_threads=num_threads)

        self.assertTrue(os.path.isfile(lldb_logfile), "lldb log file not found")
        with open(lldb_logfile, "r") as f:
            lldb_log = f.read()

        # Verify the optimization activated by looking for "Registered thread"
        # messages, which indicate threads were grouped for batching.
        registered_matches = re.findall(
            r"Registered thread 0x[0-9a-fA-F]+ stepping over "
            r"breakpoint at (0x[0-9a-fA-F]+)",
            lldb_log,
        )
        self.assertGreater(
            len(registered_matches),
            0,
            "Expected batched breakpoint step-over optimization to be "
            "used (no 'Registered thread' messages found in log).",
        )
        thread_bp_addr = registered_matches[0]

        # Verify all threads completed their step-over.
        completed_count = lldb_log.count("Completed step over breakpoint plan.")
        self.assertGreaterEqual(
            completed_count,
            num_threads,
            "Expected at least {} 'Completed step over breakpoint plan.' "
            "messages (one per thread), but got {}.".format(
                num_threads, completed_count
            ),
        )

        # Count z0/Z0 packets for the thread breakpoint address.
        # z0 = remove (disable) software breakpoint.
        # Z0 = set (enable) software breakpoint.
        # Strip the "0x" prefix and leading zeros to match the GDB packet
        # format (which uses lowercase hex without "0x" prefix).
        bp_addr_hex = thread_bp_addr[2:].lstrip("0") if thread_bp_addr else ""

        z0_count = 0  # disable packets
        Z0_count = 0  # enable packets
        initial_Z0_seen = False
        max_vcont_step_threads = 0  # largest number of s: actions in one vCont

        self.assertTrue(os.path.isfile(gdb_logfile), "gdb-remote log file not found")
        with open(gdb_logfile, "r") as f:
            for line in f:
                if "send packet: $" not in line:
                    continue

                # Match z0,<addr> (disable) or Z0,<addr> (enable).
                m = re.search(r"send packet: \$([Zz])0,([0-9a-fA-F]+),", line)
                if m and m.group(2) == bp_addr_hex:
                    if m.group(1) == "Z":
                        if not initial_Z0_seen:
                            initial_Z0_seen = True
                        else:
                            Z0_count += 1
                    else:
                        z0_count += 1

                # Count step actions in vCont packets to detect batching.
                # A batched vCont looks like: vCont;s:tid1;s:tid2;...
                vcont_m = re.search(r"send packet: \$vCont((?:;[^#]+)*)", line)
                if vcont_m:
                    actions = vcont_m.group(1)
                    step_count = len(re.findall(r";s:", actions))
                    if step_count > max_vcont_step_threads:
                        max_vcont_step_threads = step_count

        # With the optimization, fewer breakpoint toggles should occur.
        # Without optimization we'd see num_threads z0 and num_threads Z0.
        # With batching, even partial, we expect fewer toggles.
        self.assertLess(
            z0_count,
            num_threads,
            "Expected fewer than {} breakpoint disables (z0) due to "
            "batching, but got {}.".format(num_threads, z0_count),
        )
        self.assertLess(
            Z0_count,
            num_threads,
            "Expected fewer than {} breakpoint re-enables (Z0) due to "
            "batching, but got {}.".format(num_threads, Z0_count),
        )

        # Verify at least one batched vCont packet contained multiple
        # step actions, proving threads were stepped together.
        self.assertGreater(
            max_vcont_step_threads,
            1,
            "Expected at least one batched vCont packet with multiple "
            "step actions (s:), but the maximum was {}.".format(max_vcont_step_threads),
        )
