"""
Test scripted frame provider functionality.
"""

import os

import lldb
import lldbsuite.test.lldbplatformutil as lldbplatformutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import TestBase
from lldbsuite.test import lldbutil

class ScriptedFrameProviderTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    def setUp(self):
        TestBase.setUp(self)
        self.source = "main.cpp"

    def test_replace_all_frames(self):
        """Test that we can replace the entire stack."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Attach the Replace provider.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ReplaceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have exactly 3 synthetic frames.
        self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")

        # Verify frame indices and PCs (dictionary-based frames don't have custom function names).
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(frame0.GetPC(), 0x1000)

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertIn("thread_func", frame1.GetFunctionName())

        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertEqual(frame2.GetPC(), 0x3000)

    def test_prepend_frames(self):
        """Test that we can add frames before real stack."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count and PC.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import and attach Prepend provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PrependFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 2 more frames.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(new_frame_count, original_frame_count + 2)

        # Verify first 2 frames are synthetic (check PCs, not function names).
        frame0 = thread.GetFrameAtIndex(0)
        self.assertEqual(frame0.GetPC(), 0x9000)

        frame1 = thread.GetFrameAtIndex(1)
        self.assertEqual(frame1.GetPC(), 0xA000)

        # Verify frame 2 is the original real frame 0.
        frame2 = thread.GetFrameAtIndex(2)
        self.assertIn("thread_func", frame2.GetFunctionName())

    def test_append_frames(self):
        """Test that we can add frames after real stack."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()

        # Import and attach Append provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.AppendFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 1 more frame.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(new_frame_count, original_frame_count + 1)

        # Verify first frames are still real.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIn("thread_func", frame0.GetFunctionName())

        frame_n_plus_1 = thread.GetFrameAtIndex(new_frame_count - 1)
        self.assertEqual(frame_n_plus_1.GetPC(), 0x10)

    def test_scripted_frame_objects(self):
        """Test that provider can return ScriptedFrame objects."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Import the provider that returns ScriptedFrame objects.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ScriptedFrameObjectProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 5 frames.
        self.assertEqual(
            thread.GetNumFrames(), 5, "Should have 5 custom scripted frames"
        )

        # Verify frame properties from CustomScriptedFrame.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(frame0.GetFunctionName(), "custom_scripted_frame_0")
        self.assertEqual(frame0.GetPC(), 0x5000)
        self.assertTrue(frame0.IsSynthetic(), "Frame should be marked as synthetic")

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(frame1.GetPC(), 0x6000)

        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertEqual(frame2.GetFunctionName(), "custom_scripted_frame_2")
        self.assertEqual(frame2.GetPC(), 0x7000)
        self.assertTrue(frame2.IsSynthetic(), "Frame should be marked as synthetic")

    def test_applies_to_thread(self):
        """Test that applies_to_thread filters which threads get the provider."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # We should have at least 2 threads (worker threads) at the breakpoint.
        num_threads = process.GetNumThreads()
        self.assertGreaterEqual(
            num_threads, 2, "Should have at least 2 threads at breakpoint"
        )

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Collect original thread info before applying provider.
        thread_info = {}
        for i in range(num_threads):
            t = process.GetThreadAtIndex(i)
            thread_info[t.GetIndexID()] = {
                "frame_count": t.GetNumFrames(),
                "pc": t.GetFrameAtIndex(0).GetPC(),
            }

        # Register the ThreadFilterFrameProvider which only applies to thread ID 1.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ThreadFilterFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Check each thread.
        thread_id_1_found = False
        # On ARM32, FixCodeAddress clears bit 0, so synthetic PCs get modified.
        is_arm_32bit = lldbplatformutil.getArchitecture() == "arm"
        expected_synthetic_pc = 0xFFFE if is_arm_32bit else 0xFFFF

        for i in range(num_threads):
            t = process.GetThreadAtIndex(i)
            thread_id = t.GetIndexID()

            if thread_id == 1:
                # Thread with ID 1 should have synthetic frame.
                thread_id_1_found = True
                self.assertEqual(
                    t.GetNumFrames(),
                    1,
                    f"Thread with ID 1 should have 1 synthetic frame",
                )
                self.assertEqual(
                    t.GetFrameAtIndex(0).GetPC(),
                    expected_synthetic_pc,
                    f"Thread with ID 1 should have synthetic PC {expected_synthetic_pc:#x}",
                )
            else:
                # Other threads should keep their original frames.
                self.assertEqual(
                    t.GetNumFrames(),
                    thread_info[thread_id]["frame_count"],
                    f"Thread with ID {thread_id} should not be affected by provider",
                )
                self.assertEqual(
                    t.GetFrameAtIndex(0).GetPC(),
                    thread_info[thread_id]["pc"],
                    f"Thread with ID {thread_id} should have its original PC",
                )

        # We should have found at least one thread with ID 1.
        self.assertTrue(
            thread_id_1_found,
            "Should have found a thread with ID 1 to test filtering",
        )

    def test_remove_frame_provider_by_id(self):
        """Test that RemoveScriptedFrameProvider removes a specific provider by ID."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Import the test frame providers.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        original_pc = thread.GetFrameAtIndex(0).GetPC()

        # Register the first provider and get its ID.
        error = lldb.SBError()
        provider_id_1 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ReplaceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider 1: {error}")

        # Verify first provider is active (3 synthetic frames).
        self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
        self.assertEqual(
            thread.GetFrameAtIndex(0).GetPC(), 0x1000, "Should have first provider's PC"
        )

        # Register a second provider and get its ID.
        provider_id_2 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PrependFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider 2: {error}")

        # Verify IDs are different
        self.assertNotEqual(
            provider_id_1, provider_id_2, "Provider IDs should be unique"
        )

        # Now remove the first provider by ID
        result = target.RemoveScriptedFrameProvider(provider_id_1)
        self.assertSuccess(
            result, f"Should successfully remove provider with ID {provider_id_1}"
        )

        # After removing the first provider, the second provider should still be
        # active. The PrependFrameProvider adds 2 frames before the real stack.
        # Since ReplaceFrameProvider had 3 frames, and we removed it, we should now
        # have the original frames (from real stack) with PrependFrameProvider applied.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 2,
            "Should have original frames + 2 prepended frames",
        )

        # First two frames should be from PrependFrameProvider.
        self.assertEqual(
            thread.GetFrameAtIndex(0).GetPC(),
            0x9000,
            "First frame should be from PrependFrameProvider",
        )
        self.assertEqual(
            thread.GetFrameAtIndex(1).GetPC(),
            0xA000,
            "Second frame should be from PrependFrameProvider",
        )

        # Remove the second provider.
        result = target.RemoveScriptedFrameProvider(provider_id_2)
        self.assertSuccess(
            result, f"Should successfully remove provider with ID {provider_id_2}"
        )

        # After removing both providers, frames should be back to original.
        self.assertEqual(
            thread.GetNumFrames(),
            original_frame_count,
            "Should restore original frame count",
        )
        self.assertEqual(
            thread.GetFrameAtIndex(0).GetPC(),
            original_pc,
            "Should restore original PC",
        )

        # Try to remove a provider that doesn't exist.
        result = target.RemoveScriptedFrameProvider(999999)
        self.assertTrue(result.Fail(), "Should fail to remove non-existent provider")

    def test_circular_dependency_fix(self):
        """Test that accessing input_frames in __init__ doesn't cause circular dependency.

        This test verifies the fix for the circular dependency issue where:
        1. Thread::GetStackFrameList() creates the frame provider
        2. Provider's __init__ accesses input_frames and calls methods on frames
        3. SBFrame methods trigger ExecutionContextRef::GetFrameSP()
        4. Before the fix: GetFrameSP() would call Thread::GetStackFrameList() again -> circular dependency!
        5. After the fix: GetFrameSP() uses the remembered frame list -> no circular dependency

        The fix works by:
        - StackFrame stores m_frame_list_wp (weak pointer to originating list)
        - ExecutionContextRef stores m_frame_list_wp when created from a frame
        - ExecutionContextRef::GetFrameSP() tries the remembered list first before asking the thread
        """
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count and PC.
        original_frame_count = thread.GetNumFrames()
        original_pc = thread.GetFrameAtIndex(0).GetPC()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the provider that accesses input frames in __init__.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register the CircularDependencyTestProvider.
        # Before the fix, this would crash or hang due to circular dependency.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.CircularDependencyTestProvider",
            lldb.SBStructuredData(),
            error,
        )

        # If we get here without crashing, the fix is working!
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify the provider worked correctly,
        # Should have 1 synthetic frame + all original frames.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 1,
            "Should have original frames + 1 synthetic frame",
        )

        # On ARM32, FixCodeAddress clears bit 0, so synthetic PCs get modified.
        is_arm_32bit = lldbplatformutil.getArchitecture() == "arm"
        expected_synthetic_pc = 0xDEADBEEE if is_arm_32bit else 0xDEADBEEF

        # First frame should be synthetic.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(
            frame0.GetPC(),
            expected_synthetic_pc,
            f"First frame should be synthetic frame with PC {expected_synthetic_pc:#x}",
        )

        # Second frame should be the original first frame.
        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(
            frame1.GetPC(),
            original_pc,
            "Second frame should be original first frame",
        )

        # Verify we can still call methods on frames (no circular dependency!).
        for i in range(min(3, new_frame_count)):
            frame = thread.GetFrameAtIndex(i)
            self.assertIsNotNone(frame)
            # These calls should not trigger circular dependency.
            pc = frame.GetPC()
            self.assertNotEqual(pc, 0, f"Frame {i} should have valid PC")

    def test_python_source_frames(self):
        """Test that frames can point to Python source files and display properly."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register the PythonSourceFrameProvider.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PythonSourceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 3 more frames (Python frames).
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 3,
            "Should have original frames + 3 Python frames",
        )

        # Verify first three frames are Python source frames.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(
            frame0.GetFunctionName(),
            "compute_fibonacci",
            "First frame should be compute_fibonacci",
        )
        self.assertTrue(frame0.IsSynthetic(), "Frame should be marked as synthetic")
        # PC-less frames should show invalid address and not crash.
        self.assertEqual(
            frame0.GetPC(),
            lldb.LLDB_INVALID_ADDRESS,
            "PC-less frame should have LLDB_INVALID_ADDRESS",
        )

        self.assertEqual(
            frame0.GetFP(),
            lldb.LLDB_INVALID_ADDRESS,
            "PC-less frame FP should return LLDB_INVALID_ADDRESS",
        )
        self.assertEqual(
            frame0.GetSP(),
            lldb.LLDB_INVALID_ADDRESS,
            "PC-less frame SP should return LLDB_INVALID_ADDRESS",
        )
        self.assertEqual(
            frame0.GetCFA(),
            0,
            "PC-less frame CFA should return 0",
        )

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(
            frame1.GetFunctionName(),
            "process_data",
            "Second frame should be process_data",
        )
        self.assertTrue(frame1.IsSynthetic(), "Frame should be marked as synthetic")

        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertEqual(frame2.GetFunctionName(), "main", "Third frame should be main")
        self.assertTrue(frame2.IsSynthetic(), "Frame should be marked as synthetic")

        # Verify line entry information is present.
        line_entry0 = frame0.GetLineEntry()
        self.assertTrue(line_entry0.IsValid(), "Frame 0 should have a valid line entry")
        self.assertEqual(line_entry0.GetLine(), 7, "Frame 0 should point to line 7")
        file_spec0 = line_entry0.GetFileSpec()
        self.assertTrue(file_spec0.IsValid(), "Frame 0 should have valid file spec")
        self.assertEqual(
            file_spec0.GetFilename(),
            "python_helper.py",
            "Frame 0 should point to python_helper.py",
        )

        line_entry1 = frame1.GetLineEntry()
        self.assertTrue(line_entry1.IsValid(), "Frame 1 should have a valid line entry")
        self.assertEqual(line_entry1.GetLine(), 16, "Frame 1 should point to line 16")

        line_entry2 = frame2.GetLineEntry()
        self.assertTrue(line_entry2.IsValid(), "Frame 2 should have a valid line entry")
        self.assertEqual(line_entry2.GetLine(), 27, "Frame 2 should point to line 27")

        # Verify the frames display properly in backtrace.
        # This tests that PC-less frames don't show 0xffffffffffffffff.
        self.runCmd("bt")
        output = self.res.GetOutput()

        # Should show function names.
        self.assertIn("compute_fibonacci", output)
        self.assertIn("process_data", output)
        self.assertIn("main", output)

        # Should show Python file.
        self.assertIn("python_helper.py", output)

        # Should show line numbers.
        self.assertIn(":7", output)  # compute_fibonacci line.
        self.assertIn(":16", output)  # process_data line.
        self.assertIn(":27", output)  # main line.

        # Should NOT show invalid address (0xffffffffffffffff).
        self.assertNotIn("0xffffffffffffffff", output.lower())

        # Verify frame 3 is the original real frame 0.
        frame3 = thread.GetFrameAtIndex(3)
        self.assertIsNotNone(frame3)
        self.assertIn("thread_func", frame3.GetFunctionName())

    def test_valid_pc_no_module_frames(self):
        """Test that frames with valid PC but no module display correctly in backtrace."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register the ValidPCNoModuleFrameProvider.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ValidPCNoModuleFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 2 more frames (the synthetic frames).
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 2,
            "Should have original frames + 2 synthetic frames",
        )

        # Verify first two frames have valid PCs and function names.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(
            frame0.GetFunctionName(),
            "unknown_function_1",
            "First frame should be unknown_function_1",
        )
        self.assertTrue(frame0.IsSynthetic(), "Frame should be marked as synthetic")
        self.assertEqual(
            frame0.GetPC(), 0x1234000, "First frame should have PC 0x1234000"
        )

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(
            frame1.GetFunctionName(),
            "unknown_function_2",
            "Second frame should be unknown_function_2",
        )
        self.assertTrue(frame1.IsSynthetic(), "Frame should be marked as synthetic")
        self.assertEqual(
            frame1.GetPC(), 0x5678000, "Second frame should have PC 0x5678000"
        )

        # Verify the frames display properly in backtrace.
        # The backtrace should show the PC values without crashing or displaying
        # invalid addresses like 0xffffffffffffffff.
        self.runCmd("bt")
        output = self.res.GetOutput()

        # Should show function names.
        self.assertIn("unknown_function_1", output)
        self.assertIn("unknown_function_2", output)

        # Should show PC addresses in hex format.
        self.assertIn("1234000", output)
        self.assertIn("5678000", output)

        # Verify PC and function name are properly separated by space.
        self.assertIn("1234000 unknown_function_1", output)
        self.assertIn("5678000 unknown_function_2", output)

        # Should NOT show invalid address.
        self.assertNotIn("ffffff", output.lower())

        # Verify frame 2 is the original real frame 0.
        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertIn("thread_func", frame2.GetFunctionName())

    def test_chained_frame_providers(self):
        """Test that multiple frame providers chain together."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the test frame providers.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register 3 providers with different priorities.
        # Each provider adds 1 frame at the beginning.
        error = lldb.SBError()

        # Provider 1: Priority 10 - adds "foo" frame
        provider_id_1 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.AddFooFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register foo provider: {error}")

        # Provider 2: Priority 20 - adds "bar" frame
        provider_id_2 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.AddBarFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register bar provider: {error}")

        # Provider 3: Priority 30 - adds "baz" frame
        provider_id_3 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.AddBazFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register baz provider: {error}")

        # Verify we have 3 more frames (one from each provider).
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 3,
            "Should have original frames + 3 chained frames",
        )

        # Verify the chaining order: baz, bar, foo, then real frames.
        # Since priority is lower = higher, the order should be:
        # Provider 1 (priority 10) transforms real frames first -> adds "foo"
        # Provider 2 (priority 20) transforms Provider 1's output -> adds "bar"
        # Provider 3 (priority 30) transforms Provider 2's output -> adds "baz"
        # So final stack is: baz, bar, foo, real frames...

        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(
            frame0.GetFunctionName(),
            "baz",
            "Frame 0 should be 'baz' from last provider in chain",
        )
        self.assertEqual(frame0.GetPC(), 0xBAC)

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(
            frame1.GetFunctionName(),
            "bar",
            "Frame 1 should be 'bar' from second provider in chain",
        )
        self.assertEqual(frame1.GetPC(), 0xBAA)

        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertEqual(
            frame2.GetFunctionName(),
            "foo",
            "Frame 2 should be 'foo' from first provider in chain",
        )
        self.assertEqual(frame2.GetPC(), 0xF00)

        # Frame 3 should be the original real frame 0.
        frame3 = thread.GetFrameAtIndex(3)
        self.assertIsNotNone(frame3)
        self.assertIn("thread_func", frame3.GetFunctionName())

    def test_get_values(self):
        """Test a frame that provides values."""
        self.build()
        # Set the breakpoint after the variable_in_main variable exists and can be queried.
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self,
            "Breakpoint for variable tests",
            lldb.SBFileSpec(self.source),
            only_one_thread=False,
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the test frame providers.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register a provider that can provide variables.
        error = lldb.SBError()
        target.RegisterScriptedFrameProvider(
            "test_frame_providers.ValueProvidingFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")

        # Verify we have 1 more frame.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 1,
            "Should have original frames + 1 extra frames",
        )

        # Check that we can get variables from this frame.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        # Get every variable visible at this point
        variables = frame0.GetVariables(True, True, True, False)
        self.assertTrue(variables.IsValid())
        self.assertEqual(variables.GetSize(), 1)

        # Check that we can get values from paths. `_handler_one` is a special
        # value we provide through only our expression handler in the frame
        # implementation.
        one = frame0.GetValueForVariablePath("_handler_one")
        self.assertEqual(one.unsigned, 1)
        var = frame0.GetValueForVariablePath("variable_in_main")
        # The names won't necessarily match, but the values should (the frame renames the SBValue)
        self.assertEqual(var.unsigned, variables.GetValueAtIndex(0).unsigned)
        varp1 = frame0.GetValueForVariablePath("variable_in_main + 1")
        self.assertEqual(varp1.unsigned, 124)

    def test_frame_validity_after_step(self):
        """Test that SBFrame references from ScriptedFrameProvider remain valid after stepping.

        This test verifies that ExecutionContextRef properly handles frame list identifiers
        when the underlying stack changes. After stepping, old frame references should become
        invalid gracefully without crashing.
        """
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register a provider that prepends synthetic frames.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PrependFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")

        # Get frame references before stepping.
        frame0_before = thread.GetFrameAtIndex(0)
        frame1_before = thread.GetFrameAtIndex(1)
        frame2_before = thread.GetFrameAtIndex(2)

        self.assertIsNotNone(frame0_before)
        self.assertIsNotNone(frame1_before)
        self.assertIsNotNone(frame2_before)

        # Verify frames are valid and have expected PCs.
        self.assertTrue(frame0_before.IsValid(), "Frame 0 should be valid before step")
        self.assertTrue(frame1_before.IsValid(), "Frame 1 should be valid before step")
        self.assertTrue(frame2_before.IsValid(), "Frame 2 should be valid before step")

        pc0_before = frame0_before.GetPC()
        pc1_before = frame1_before.GetPC()
        pc2_before = frame2_before.GetPC()

        self.assertEqual(pc0_before, 0x9000, "Frame 0 should have synthetic PC 0x9000")
        self.assertEqual(pc1_before, 0xA000, "Frame 1 should have synthetic PC 0xA000")

        # Step the thread, which will invalidate the old frame list.
        thread.StepInstruction(False)

        # After stepping, the frame list has changed. Old frame references should
        # detect this and become invalid, but shouldn't crash.
        # The key here is that GetPC() and other operations should handle the
        # "frame provider no longer available" case gracefully.

        # Try to access the old frames - they should either:
        # 1. Return invalid/default values gracefully, or
        # 2. Still work if the frame provider is re-applied.

        # Get new frames after stepping.
        frame0_after = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0_after)
        self.assertTrue(
            frame0_after.IsValid(), "New frame 0 should be valid after step"
        )

        # The old frame references might or might not be valid depending on whether
        # the frame provider is still active. What's important is that accessing
        # them doesn't crash and handles the situation gracefully.
        # We'll just verify we can call methods on them without crashing.
        try:
            _ = frame0_before.GetPC()
            _ = frame0_before.IsValid()
            _ = frame0_before.GetFunctionName()
        except Exception as e:
            self.fail(f"Accessing old frame reference should not crash: {e}")

    def test_provider_lifecycle_with_frame_validity(self):
        """Test provider registration/removal at breakpoints and SBFrame validity across lifecycle.

        This test verifies:
        1. Registering a provider while stopped at a breakpoint.
        2. SBFrame references from synthetic frames persist across continues.
        3. SBFrame references can access variables in real frames while provider is active.
        4. Removing a provider while stopped at a breakpoint.
        5. SBFrame references from removed provider don't crash when accessed.
        """
        self.build()
        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
        self.assertTrue(target.IsValid(), "Target should be valid")

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Set up breakpoints at the return statements in foo, bar, and baz.
        # This ensures local variables are initialized.
        bp_foo = target.BreakpointCreateBySourceRegex(
            "Break in foo", lldb.SBFileSpec(self.source)
        )
        bp_bar = target.BreakpointCreateBySourceRegex(
            "Break in bar", lldb.SBFileSpec(self.source)
        )
        bp_baz = target.BreakpointCreateBySourceRegex(
            "Break in baz", lldb.SBFileSpec(self.source)
        )

        self.assertTrue(bp_foo.IsValid(), "Breakpoint at foo should be valid")
        self.assertTrue(bp_bar.IsValid(), "Breakpoint at bar should be valid")
        self.assertTrue(bp_baz.IsValid(), "Breakpoint at baz should be valid")

        # Launch the process.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        self.assertTrue(process.IsValid(), "Process should be valid")

        # We should hit the foo breakpoint first.
        self.assertEqual(
            process.GetState(), lldb.eStateStopped, "Process should be stopped at foo"
        )
        thread = process.GetSelectedThread()
        self.assertIsNotNone(thread, "Should have a selected thread")

        # Register the provider at foo breakpoint.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PrependFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Get individual frames BEFORE getting the full backtrace.
        # This tests accessing frames before forcing evaluation of all frames.
        frame0 = thread.GetFrameAtIndex(0)
        frame1 = thread.GetFrameAtIndex(1)
        frame2 = thread.GetFrameAtIndex(2)

        self.assertIsNotNone(frame0, "Frame 0 should exist")
        self.assertIsNotNone(frame1, "Frame 1 should exist")
        self.assertIsNotNone(frame2, "Frame 2 should exist")

        # First two frames should be synthetic with expected PCs.
        pc0 = frame0.GetPC()
        pc1 = frame1.GetPC()

        self.assertEqual(pc0, 0x9000, "Frame 0 should have synthetic PC 0x9000")
        self.assertEqual(pc1, 0xA000, "Frame 1 should have synthetic PC 0xA000")

        # Frame 2 should be the real foo frame.
        self.assertIn("foo", frame2.GetFunctionName(), "Frame 2 should be in foo")

        # Save references to the synthetic frames.
        saved_frames = [frame0, frame1, frame2]

        # Test accessing saved frames at foo BEFORE getting full backtrace.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[2].GetFunctionName()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at foo before full backtrace should not crash: {e}"
            )

        # Now verify the provider is active by checking frame count.
        # PrependFrameProvider adds 2 synthetic frames.
        # This forces a full backtrace evaluation.
        original_frame_count = thread.GetNumFrames()
        self.assertGreater(
            original_frame_count,
            2,
            "Should have at least synthetic frames + real frames",
        )

        # Test accessing saved frames at foo AFTER getting full backtrace.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[2].GetFunctionName()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at foo after full backtrace should not crash: {e}"
            )

        # Verify we can access variables in frame2 (real frame).
        foo_local = frame2.FindVariable("foo_local")
        self.assertTrue(foo_local.IsValid(), "Should find foo_local variable")
        self.assertEqual(
            foo_local.GetValueAsUnsigned(), 20, "foo_local should be 20 (10 * 2)"
        )

        # Continue to bar breakpoint.
        threads = lldbutil.continue_to_breakpoint(process, bp_bar)
        self.assertIsNotNone(threads, "Should have stopped at bar breakpoint")
        self.assertEqual(len(threads), 1, "Should have one thread stopped at bar")
        thread = threads[0]

        # Verify the saved frames are still accessible without crashing at bar.
        # Do this BEFORE getting the full backtrace.
        # Note: They might not be "valid" in the traditional sense since we've moved
        # to a different execution context, but they shouldn't crash.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at bar before full backtrace should not crash: {e}"
            )

        # Verify the provider is still active by getting frame count.
        # This forces full backtrace evaluation.
        current_frame_count = thread.GetNumFrames()
        self.assertGreater(
            current_frame_count, 2, "Should still have synthetic frames at bar"
        )

        # Access the saved frames again AFTER getting the full backtrace.
        # This ensures that forcing a full backtrace evaluation doesn't break
        # the saved frame references.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at bar after full backtrace should not crash: {e}"
            )

        # Get current frames at bar.
        bar_frame0 = thread.GetFrameAtIndex(0)
        bar_frame1 = thread.GetFrameAtIndex(1)
        bar_frame2 = thread.GetFrameAtIndex(2)

        # Verify current frames have synthetic PCs.
        self.assertEqual(
            bar_frame0.GetPC(), 0x9000, "Frame 0 at bar should have synthetic PC"
        )
        self.assertEqual(
            bar_frame1.GetPC(), 0xA000, "Frame 1 at bar should have synthetic PC"
        )
        self.assertIn("bar", bar_frame2.GetFunctionName(), "Frame 2 should be in bar")

        # Verify we can access variables in the bar frame.
        bar_local = bar_frame2.FindVariable("bar_local")
        self.assertTrue(bar_local.IsValid(), "Should find bar_local variable")
        self.assertEqual(
            bar_local.GetValueAsUnsigned(), 25, "bar_local should be 25 (5 * 5)"
        )

        # Continue to baz breakpoint.
        threads = lldbutil.continue_to_breakpoint(process, bp_baz)
        self.assertIsNotNone(threads, "Should have stopped at baz breakpoint")
        self.assertEqual(len(threads), 1, "Should have one thread stopped at baz")
        thread = threads[0]

        # Verify the saved frames are still accessible without crashing at baz.
        # Do this BEFORE getting the full backtrace.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[2].GetFunctionName()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at baz before full backtrace should not crash: {e}"
            )

        # Get the frame count to force full backtrace evaluation at baz.
        baz_frame_count = thread.GetNumFrames()
        self.assertGreater(
            baz_frame_count, 2, "Should still have synthetic frames at baz"
        )

        # Verify the saved frames are still accessible AFTER getting full backtrace at baz.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[2].GetFunctionName()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at baz after full backtrace should not crash: {e}"
            )

        # Now manually remove the provider.
        result = target.RemoveScriptedFrameProvider(provider_id)
        self.assertSuccess(
            result, f"Should successfully remove provider with ID {provider_id}"
        )
        # Verify frames no longer have synthetic frames.
        final_frame_count = thread.GetNumFrames()

        # Without the provider, we should have fewer frames (no synthetic ones).
        self.assertLess(
            final_frame_count,
            original_frame_count,
            "Frame count should decrease after provider removal",
        )

        # First frame should now be the real baz frame (no synthetic frames).
        baz_frame0 = thread.GetFrameAtIndex(0)
        self.assertIn(
            "baz", baz_frame0.GetFunctionName(), "Frame 0 should now be real baz frame"
        )

        # The synthetic PC values should no longer appear.
        for i in range(final_frame_count):
            frame = thread.GetFrameAtIndex(i)
            pc = frame.GetPC()
            self.assertNotEqual(
                pc, 0x9000, f"Frame {i} should not have synthetic PC 0x9000"
            )
            self.assertNotEqual(
                pc, 0xA000, f"Frame {i} should not have synthetic PC 0xA000"
            )

        # Verify the originally saved frames are now truly invalid/stale.
        # They should still not crash when accessed.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[0].IsValid()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[1].IsValid()
        except Exception as e:
            self.fail(f"Accessing invalidated frames should not crash: {e}")

    def test_event_broadcasting(self):
        """Test that adding/removing frame providers broadcasts eBroadcastBitStackChanged."""
        self.build()

        listener = lldb.SBListener("stack_changed_listener")
        listener.StartListeningForEventClass(
            self.dbg,
            lldb.SBThread.GetBroadcasterClassName(),
            lldb.SBThread.eBroadcastBitStackChanged,
        )

        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        expected_thread_ids = {
            process.GetThreadAtIndex(i).GetIndexID()
            for i in range(process.GetNumThreads())
        }

        def collect_stack_changed_thread_ids(count):
            event = lldb.SBEvent()
            thread_ids = set()
            for _ in range(count):
                if not listener.WaitForEvent(5, event):
                    break
                self.assertEqual(
                    event.GetType(),
                    lldb.SBThread.eBroadcastBitStackChanged,
                    "Event should be stack changed",
                )
                thread_ids.add(lldb.SBThread.GetThreadFromEvent(event).GetIndexID())
            return thread_ids

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # 1. Test registration.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ReplaceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertSuccess(error, f"Failed to register provider: {error}")
        self.assertEqual(
            collect_stack_changed_thread_ids(len(expected_thread_ids)),
            expected_thread_ids,
            "All threads should broadcast eBroadcastBitStackChanged on registration",
        )

        # 2. Test removal.
        result = target.RemoveScriptedFrameProvider(provider_id)
        self.assertSuccess(result, f"Failed to remove provider: {result}")
        self.assertEqual(
            collect_stack_changed_thread_ids(len(expected_thread_ids)),
            expected_thread_ids,
            "All threads should broadcast eBroadcastBitStackChanged on removal",
        )

        # 3. Test clear.
        target.RegisterScriptedFrameProvider(
            "test_frame_providers.ReplaceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        # Consume registration
        collect_stack_changed_thread_ids(len(expected_thread_ids))

        self.runCmd("target frame-provider clear")
        self.assertEqual(
            collect_stack_changed_thread_ids(len(expected_thread_ids)),
            expected_thread_ids,
            "All threads should broadcast eBroadcastBitStackChanged on clear",
        )