"""
Test SBProcess APIs, including ReadMemory(), WriteMemory(), and others.
"""

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


class ProcessAPITestCase(TestBase):
    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line number to break inside main().
        self.line = line_number(
            "main.cpp", "// Set break point at this line and check variable 'my_char'."
        )

    def test_scripted_implementation(self):
        self.build()
        exe = self.getBuildArtifact("a.out")

        (target, process, _, _) = lldbutil.run_to_source_breakpoint(
            self, "Set break point", lldb.SBFileSpec("main.cpp")
        )

        self.assertTrue(process, PROCESS_IS_VALID)
        self.assertEqual(process.GetScriptedImplementation(), None)

    def test_is_live_debug_session(self):
        """Test that a launched process reports as a live debug session."""
        self.build()

        (target, process, _, _) = lldbutil.run_to_source_breakpoint(
            self, "Set break point", lldb.SBFileSpec("main.cpp")
        )

        self.assertTrue(process, PROCESS_IS_VALID)
        self.assertTrue(process.IsLiveDebugSession())

    def test_is_live_debug_session_invalid_process(self):
        """Test that an invalid process is not reported as a live session."""
        process = lldb.SBProcess()
        self.assertFalse(process.IsValid())
        self.assertFalse(process.IsLiveDebugSession())

    def test_read_memory(self):
        """Test Python SBProcess.ReadMemory() API."""
        self.build()
        _, process, thread, _ = lldbutil.run_to_line_breakpoint(
            self, lldb.SBFileSpec("main.cpp"), self.line
        )
        frame = thread.GetFrameAtIndex(0)

        # Get the SBValue for the file static variable 'my_char'.
        val = frame.FindValue("my_char", lldb.eValueTypeVariableStatic)
        self.DebugSBValue(val)

        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
        # expect to get a Python string as the result object!
        error = lldb.SBError()
        self.assertFalse(val.TypeIsPointerType())
        content = process.ReadMemory(val.AddressOf().GetValueAsUnsigned(), 1, error)
        if not error.Success():
            self.fail("SBProcess.ReadMemory() failed")
        if self.TraceOn():
            print("memory content:", content)

        self.expect(
            content,
            "Result from SBProcess.ReadMemory() matches our expected output: 'x'",
            exe=False,
            startstr=b"x",
        )

        # Read (char *)my_char_ptr.
        val = frame.FindValue("my_char_ptr", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)
        cstring = process.ReadCStringFromMemory(val.GetValueAsUnsigned(), 256, error)
        if not error.Success():
            self.fail("SBProcess.ReadCStringFromMemory() failed")
        if self.TraceOn():
            print("cstring read is:", cstring)

        self.expect(
            cstring,
            "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
            exe=False,
            startstr="Does it work?",
        )

        # Get the SBValue for the global variable 'my_cstring'.
        val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)

        # Due to the typemap magic (see lldb.swig), we pass in 256 to read at most 256 bytes
        # from the address, and expect to get a Python string as the result
        # object!
        self.assertFalse(val.TypeIsPointerType())
        cstring = process.ReadCStringFromMemory(
            val.AddressOf().GetValueAsUnsigned(), 256, error
        )
        if not error.Success():
            self.fail("SBProcess.ReadCStringFromMemory() failed")
        if self.TraceOn():
            print("cstring read is:", cstring)

        self.expect(
            cstring,
            "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
            exe=False,
            startstr="lldb.SBProcess.ReadCStringFromMemory() works!",
        )

        # Get the SBValue for the global variable 'my_uint32'.
        val = frame.FindValue("my_uint32", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)

        # Due to the typemap magic (see lldb.swig), we pass in 4 to read 4 bytes
        # from the address, and expect to get an int as the result!
        self.assertFalse(val.TypeIsPointerType())
        my_uint32 = process.ReadUnsignedFromMemory(
            val.AddressOf().GetValueAsUnsigned(), 4, error
        )
        if not error.Success():
            self.fail("SBProcess.ReadCStringFromMemory() failed")
        if self.TraceOn():
            print("uint32 read is:", my_uint32)

        if my_uint32 != 12345:
            self.fail(
                "Result from SBProcess.ReadUnsignedFromMemory() does not match our expected output"
            )

    def test_write_memory(self):
        """Test Python SBProcess.WriteMemory() API."""
        self.build()
        _, process, thread, _ = lldbutil.run_to_line_breakpoint(
            self, lldb.SBFileSpec("main.cpp"), self.line
        )
        frame = thread.GetFrameAtIndex(0)

        # Get the SBValue for the static variable 'my_char'.
        val = frame.FindValue("my_char", lldb.eValueTypeVariableStatic)
        self.DebugSBValue(val)

        # If the variable does not have a load address, there's no sense
        # continuing.
        if not val.GetLocation().startswith("0x"):
            return

        # OK, let's get the hex location of the variable.
        location = int(val.GetLocation(), 16)

        # The program logic makes the 'my_char' variable to have memory content as 'x'.
        # But we want to use the WriteMemory() API to assign 'a' to the
        # variable.

        # Now use WriteMemory() API to write 'a' into the global variable.
        error = lldb.SBError()
        result = process.WriteMemory(location, "a", error)
        if not error.Success() or result != 1:
            self.fail("SBProcess.WriteMemory() failed")

        # Read from the memory location.  This time it should be 'a'.
        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
        # expect to get a Python string as the result object!
        content = process.ReadMemory(location, 1, error)
        if not error.Success():
            self.fail("SBProcess.ReadMemory() failed")
        if self.TraceOn():
            print("memory content:", content)

        self.expect(
            content,
            "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
            exe=False,
            startstr=b"a",
        )

        # Get the SBValue for the global variable 'my_cstring'.
        val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)

        addr = val.AddressOf().GetValueAsUnsigned()

        # Write an empty string to memory
        bytes_written = process.WriteMemoryAsCString(addr, "", error)
        self.assertEqual(bytes_written, 0)
        if not error.Success():
            self.fail("SBProcess.WriteMemoryAsCString() failed")

        message = "Hello!"
        bytes_written = process.WriteMemoryAsCString(addr, message, error)
        self.assertEqual(bytes_written, len(message) + 1)
        if not error.Success():
            self.fail("SBProcess.WriteMemoryAsCString() failed")

        cstring = process.ReadCStringFromMemory(
            val.AddressOf().GetValueAsUnsigned(), 256, error
        )
        if not error.Success():
            self.fail("SBProcess.ReadCStringFromMemory() failed")

        self.assertEqual(cstring, message)

    def test_access_my_int(self):
        """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
        self.build()
        _, process, thread, _ = lldbutil.run_to_line_breakpoint(
            self, lldb.SBFileSpec("main.cpp"), self.line
        )
        frame = thread.GetFrameAtIndex(0)

        # Get the SBValue for the global variable 'my_int'.
        val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)

        # If the variable does not have a load address, there's no sense
        # continuing.
        if not val.GetLocation().startswith("0x"):
            return

        # OK, let's get the hex location of the variable.
        location = int(val.GetLocation(), 16)

        # Note that the canonical from of the bytearray is little endian.
        from lldbsuite.test.lldbutil import int_to_bytearray, bytearray_to_int

        byteSize = val.GetByteSize()
        bytes = int_to_bytearray(256, byteSize)

        byteOrder = process.GetByteOrder()
        if byteOrder == lldb.eByteOrderBig:
            bytes.reverse()
        elif byteOrder == lldb.eByteOrderLittle:
            pass
        else:
            # Neither big endian nor little endian?  Return for now.
            # Add more logic here if we want to handle other types.
            return

        # The program logic makes the 'my_int' variable to have int type and value of 0.
        # But we want to use the WriteMemory() API to assign 256 to the
        # variable.

        # Now use WriteMemory() API to write 256 into the global variable.
        error = lldb.SBError()
        result = process.WriteMemory(location, bytes, error)
        if not error.Success() or result != byteSize:
            self.fail("SBProcess.WriteMemory() failed")

        # Make sure that the val we got originally updates itself to notice the
        # change:
        self.expect(
            val.GetValue(),
            "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
            exe=False,
            startstr="256",
        )

        # And for grins, get the SBValue for the global variable 'my_int'
        # again, to make sure that also tracks the new value:
        val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
        self.expect(
            val.GetValue(),
            "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
            exe=False,
            startstr="256",
        )

        # Now read the memory content.  The bytearray should have (byte)1 as
        # the second element.
        content = process.ReadMemory(location, byteSize, error)
        if not error.Success():
            self.fail("SBProcess.ReadMemory() failed")

        # The bytearray_to_int utility function expects a little endian
        # bytearray.
        if byteOrder == lldb.eByteOrderBig:
            content = bytearray(content, "ascii")
            content.reverse()

        new_value = bytearray_to_int(content, byteSize)
        if new_value != 256:
            self.fail("Memory content read from 'my_int' does not match (int)256")

        # Dump the memory content....
        if self.TraceOn():
            for i in content:
                print("byte:", i)

    def test_remote_launch(self):
        """Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())

        if self.TraceOn():
            print("process state:", state_type_to_str(process.GetState()))
        self.assertNotEqual(process.GetState(), lldb.eStateConnected)

        error = lldb.SBError()
        success = process.RemoteLaunch(
            None, None, None, None, None, None, 0, False, error
        )
        self.assertTrue(
            not success,
            "RemoteLaunch() should fail for process state != eStateConnected",
        )

    def test_get_num_supported_hardware_watchpoints(self):
        """Test SBProcess.GetNumSupportedHardwareWatchpoints() API with a process."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        # Launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())

        error = lldb.SBError()
        num = process.GetNumSupportedHardwareWatchpoints(error)
        if self.TraceOn() and error.Success():
            print("Number of supported hardware watchpoints: %d" % num)

    @no_debug_info_test
    @skipIfRemote
    @skipIfWasm  # the Wasm platform cannot look a process up by its id
    def test_get_process_info(self):
        """Test SBProcess::GetProcessInfo() API with a locally launched process."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Launch the process and stop at the entry point.
        launch_info = target.GetLaunchInfo()
        launch_info.SetWorkingDirectory(self.get_process_working_directory())
        launch_flags = launch_info.GetLaunchFlags()
        launch_flags |= lldb.eLaunchFlagStopAtEntry
        launch_info.SetLaunchFlags(launch_flags)
        error = lldb.SBError()
        process = target.Launch(launch_info, error)

        if not error.Success():
            self.fail("Failed to launch process")

        # Verify basic process info can be retrieved successfully
        process_info = process.GetProcessInfo()
        self.assertTrue(process_info.IsValid())
        file_spec = process_info.GetExecutableFile()
        self.assertTrue(file_spec.IsValid())
        process_name = process_info.GetName()
        self.assertIsNotNone(process_name, "Process has a name")
        self.assertGreater(len(process_name), 0, "Process name isn't blank")
        self.assertEqual(file_spec.GetFilename(), "a.out")
        self.assertNotEqual(
            process_info.GetProcessID(),
            lldb.LLDB_INVALID_PROCESS_ID,
            "Process ID is valid",
        )
        triple = process_info.GetTriple()
        self.assertIsNotNone(triple, "Process has a triple")

        # Additional process info varies by platform, so just check that
        # whatever info was retrieved is consistent and nothing blows up.
        if process_info.UserIDIsValid():
            self.assertNotEqual(
                process_info.GetUserID(), lldb.UINT32_MAX, "Process user ID is valid"
            )
        else:
            self.assertEqual(
                process_info.GetUserID(), lldb.UINT32_MAX, "Process user ID is invalid"
            )

        if process_info.GroupIDIsValid():
            self.assertNotEqual(
                process_info.GetGroupID(), lldb.UINT32_MAX, "Process group ID is valid"
            )
        else:
            self.assertEqual(
                process_info.GetGroupID(),
                lldb.UINT32_MAX,
                "Process group ID is invalid",
            )

        if process_info.EffectiveUserIDIsValid():
            self.assertNotEqual(
                process_info.GetEffectiveUserID(),
                lldb.UINT32_MAX,
                "Process effective user ID is valid",
            )
        else:
            self.assertEqual(
                process_info.GetEffectiveUserID(),
                lldb.UINT32_MAX,
                "Process effective user ID is invalid",
            )

        if process_info.EffectiveGroupIDIsValid():
            self.assertNotEqual(
                process_info.GetEffectiveGroupID(),
                lldb.UINT32_MAX,
                "Process effective group ID is valid",
            )
        else:
            self.assertEqual(
                process_info.GetEffectiveGroupID(),
                lldb.UINT32_MAX,
                "Process effective group ID is invalid",
            )

        process_info.GetParentProcessID()

    @expectedFailureWindows  # Not yet implemented.
    @skipIfWasm  # the Wasm platform cannot look a process up by its id
    def test_get_process_info_arguments(self):
        """Test SBProcessInfo Arguments returns the correct values."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Launch the process and stop at the entry point.
        launch_info = target.GetLaunchInfo()
        launch_info.SetWorkingDirectory(self.get_process_working_directory())
        launch_flags = launch_info.GetLaunchFlags()
        launch_flags |= lldb.eLaunchFlagStopAtEntry
        launch_info.SetLaunchFlags(launch_flags)
        expected_arguments = ["10", "qu'o'tes\"", "hello", "מזל טוב"]
        launch_info.SetArguments(expected_arguments, False)
        error = lldb.SBError()
        process = target.Launch(launch_info, error)

        if not error.Success():
            self.fail("Failed to launch process")

        process_info: lldb.SBProcessInfo = process.GetProcessInfo()
        self.assertListEqual(process_info.arguments, expected_arguments)
        self.assertEqual(process_info.GetNumArguments(), 4)
        self.assertEqual(process_info.GetArgumentAtIndex(0), "10")
        self.assertEqual(process_info.GetArgumentAtIndex(1), "qu'o'tes\"")
        self.assertEqual(process_info.GetArgumentAtIndex(2), "hello")
        self.assertEqual(process_info.GetArgumentAtIndex(3), "מזל טוב")
        self.assertEqual(process_info.GetArgumentAtIndex(4), None)

    @skipIfWasm  # the test reads the allocation back with an expression
    def test_allocate_deallocate_memory(self):
        """Test Python SBProcess.AllocateMemory() and SBProcess.DeallocateMemory() APIs."""
        self.build()
        (
            target,
            process,
            main_thread,
            main_breakpoint,
        ) = lldbutil.run_to_source_breakpoint(
            self, "// Set break point at this line", lldb.SBFileSpec("main.cpp")
        )

        # Allocate a block of memory in the target process
        error = lldb.SBError()
        addr = process.AllocateMemory(16384, lldb.ePermissionsReadable, error)
        if not error.Success() or addr == lldb.LLDB_INVALID_ADDRESS:
            self.fail("SBProcess.AllocateMemory() failed")

        # Now use WriteMemory() API to write 'a' into the allocated
        # memory. Note that the debugger can do this even though the
        # block is not set writable.
        result = process.WriteMemory(addr, "a", error)
        if not error.Success() or result != 1:
            self.fail("SBProcess.WriteMemory() failed")

        # Read from the memory location.  This time it should be 'a'.
        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
        # expect to get a Python string as the result object!
        content = process.ReadMemory(addr, 1, error)
        if not error.Success():
            self.fail("SBProcess.ReadMemory() failed")
        if self.TraceOn():
            print("memory content:", content)

        self.expect(
            content,
            "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
            exe=False,
            startstr=b"a",
        )

        # Verify that the process itself can read the allocated memory
        frame = main_thread.GetFrameAtIndex(0)
        val = frame.EvaluateExpression(
            "test_read(reinterpret_cast<char *>({:#x}))".format(addr)
        )
        self.expect(
            val.GetValue(),
            "Result of test_read() matches expected output 'a'",
            exe=False,
            startstr="'a'",
        )

        # Verify that the process cannot write into the block
        val = frame.EvaluateExpression(
            "test_write(reinterpret_cast<char *>({:#x}), 'b')".format(addr)
        )
        if val.GetError().Success():
            self.fail(
                "test_write() to allocated memory without write permission unexpectedly succeeded"
            )

        # Deallocate the memory
        error = process.DeallocateMemory(addr)
        if not error.Success():
            self.fail("SBProcess.DeallocateMemory() failed")
