"""
Test that lldb ignores the Windows loader breakpoint when attaching to a
process, but still stops at a genuine breakpoint instruction (an int3) that
lives in the program's own code.
"""

import ctypes

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


class WindowsAttachLoaderBreakpointTestCase(TestBase):
    def create_suspended_process(self, exe):
        """Create ``exe`` suspended and return its (pid, hProcess, hThread).

        This mirrors what the lldb-dap runInTerminal launcher does on Windows:
        the debuggee is started with CREATE_SUSPENDED so lldb can attach while
        the process is still being initialized by the loader. The launcher then
        resumes the main thread once the debugger has attached.
        """
        from ctypes import wintypes

        CREATE_SUSPENDED = 0x00000004

        class STARTUPINFOW(ctypes.Structure):
            _fields_ = [
                ("cb", wintypes.DWORD),
                ("lpReserved", wintypes.LPWSTR),
                ("lpDesktop", wintypes.LPWSTR),
                ("lpTitle", wintypes.LPWSTR),
                ("dwX", wintypes.DWORD),
                ("dwY", wintypes.DWORD),
                ("dwXSize", wintypes.DWORD),
                ("dwYSize", wintypes.DWORD),
                ("dwXCountChars", wintypes.DWORD),
                ("dwYCountChars", wintypes.DWORD),
                ("dwFillAttribute", wintypes.DWORD),
                ("dwFlags", wintypes.DWORD),
                ("wShowWindow", wintypes.WORD),
                ("cbReserved2", wintypes.WORD),
                ("lpReserved2", ctypes.POINTER(ctypes.c_byte)),
                ("hStdInput", wintypes.HANDLE),
                ("hStdOutput", wintypes.HANDLE),
                ("hStdError", wintypes.HANDLE),
            ]

        class PROCESS_INFORMATION(ctypes.Structure):
            _fields_ = [
                ("hProcess", wintypes.HANDLE),
                ("hThread", wintypes.HANDLE),
                ("dwProcessId", wintypes.DWORD),
                ("dwThreadId", wintypes.DWORD),
            ]

        kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
        kernel32.CreateProcessW.argtypes = [
            wintypes.LPCWSTR,
            wintypes.LPWSTR,
            ctypes.c_void_p,
            ctypes.c_void_p,
            wintypes.BOOL,
            wintypes.DWORD,
            ctypes.c_void_p,
            wintypes.LPCWSTR,
            ctypes.POINTER(STARTUPINFOW),
            ctypes.POINTER(PROCESS_INFORMATION),
        ]
        kernel32.CreateProcessW.restype = wintypes.BOOL

        startupinfo = STARTUPINFOW()
        startupinfo.cb = ctypes.sizeof(STARTUPINFOW)
        process_information = PROCESS_INFORMATION()

        # CreateProcessW may modify the command-line buffer, so it must be
        # writable.
        command_line = ctypes.create_unicode_buffer('"{}"'.format(exe))

        if not kernel32.CreateProcessW(
            exe,
            command_line,
            None,
            None,
            False,
            CREATE_SUSPENDED,
            None,
            None,
            ctypes.byref(startupinfo),
            ctypes.byref(process_information),
        ):
            raise OSError(ctypes.get_last_error(), "CreateProcessW failed")

        return (
            process_information.dwProcessId,
            process_information.hProcess,
            process_information.hThread,
        )

    @requireWindows
    def test_attach_ignores_loader_breakpoint(self):
        """
        lldb must not report the loader's int3 (raised in a system module while
        attaching) as a user-visible stop, but must still stop at the
        __builtin_debugtrap() in the program's own code.
        """
        self.build()
        exe = self.getBuildArtifact("a.out")

        pid, hProcess, hThread = self.create_suspended_process(exe)

        kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
        kernel32.ResumeThread.argtypes = [ctypes.c_void_p]
        kernel32.ResumeThread.restype = ctypes.c_uint

        def cleanup():
            kernel32.TerminateProcess(hProcess, 0)
            kernel32.CloseHandle(hThread)
            kernel32.CloseHandle(hProcess)

        self.addTearDownHook(cleanup)

        self.dbg.SetAsync(False)

        # Attach while the process is suspended and still being initialized.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        error = lldb.SBError()
        process = target.AttachToProcessWithID(self.dbg.GetListener(), pid, error)
        self.assertSuccess(error, "attach to the suspended process")
        self.assertState(process.GetState(), lldb.eStateStopped)

        self.assertNotEqual(
            kernel32.ResumeThread(hThread), 0xFFFFFFFF, "ResumeThread failed"
        )

        # Continuing must run past the loader breakpoint (skipped because it is
        # raised in a system module) and stop at the program's own
        # __builtin_debugtrap().
        process.Continue()
        self.assertState(process.GetState(), lldb.eStateStopped)

        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonException)
        self.assertIsNotNone(
            thread, "the process should stop at the user __builtin_debugtrap()"
        )
        function_name = thread.GetFrameAtIndex(0).GetFunctionName()
        self.assertIn(
            "main",
            function_name,
            "expected to stop at the program's __builtin_debugtrap(), but "
            "stopped in '{}' (a spurious loader breakpoint in a system module "
            "was not skipped)".format(function_name),
        )

        process.Continue()
        self.assertState(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), 0)
