"""
Make sure the getting a variable path works and doesn't crash.
"""


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


class TestVTableValue(TestBase):
    # If your test case doesn't stress debug info, then
    # set this to true.  That way it won't be run once for
    # each debug info format.
    NO_DEBUG_INFO_TESTCASE = True

    @skipIf(compiler="clang", compiler_version=["<", "9.0"])
    @skipUnlessPlatform(["linux", "macosx"])
    def test_vtable(self):
        self.build()
        lldbutil.run_to_source_breakpoint(
            self, "At the end", lldb.SBFileSpec("main.cpp")
        )

        # Test a shape instance to make sure we get the vtable correctly.
        shape = self.frame().FindVariable("shape")
        vtable = shape.GetVTable()
        self.assertEqual(vtable.GetName(), "vtable for Shape")
        self.assertEqual(vtable.GetTypeName(), "vtable for Shape")
        # Make sure we have the right number of virtual functions in our vtable
        # for the shape class.
        self.assertEqual(vtable.GetNumChildren(), 4)

        # Verify vtable address
        vtable_addr = vtable.GetValueAsUnsigned(0)
        expected_addr = self.expected_vtable_addr(shape)
        self.assertEqual(vtable_addr, expected_addr)

        for idx, vtable_entry in enumerate(vtable.children):
            self.verify_vtable_entry(vtable_entry, vtable_addr, idx)

        # Test a shape reference to make sure we get the vtable correctly.
        shape = self.frame().FindVariable("shape_ref")
        vtable = shape.GetVTable()
        self.assertEqual(vtable.GetName(), "vtable for Shape")
        self.assertEqual(vtable.GetTypeName(), "vtable for Shape")
        # Make sure we have the right number of virtual functions in our vtable
        # for the shape class.
        self.assertEqual(vtable.GetNumChildren(), 4)

        # Verify vtable address
        vtable_addr = vtable.GetValueAsUnsigned(0)
        expected_addr = self.expected_vtable_addr(shape)
        self.assertEqual(vtable_addr, expected_addr)

        for idx, vtable_entry in enumerate(vtable.children):
            self.verify_vtable_entry(vtable_entry, vtable_addr, idx)

        # Test we get the right vtable for the Rectangle instance.
        rect = self.frame().FindVariable("rect")
        vtable = rect.GetVTable()
        self.assertEqual(vtable.GetName(), "vtable for Rectangle")
        self.assertEqual(vtable.GetTypeName(), "vtable for Rectangle")

        # Make sure we have the right number of virtual functions in our vtable
        # with the extra virtual function added by the Rectangle class
        self.assertEqual(vtable.GetNumChildren(), 5)

        # Verify vtable address
        vtable_addr = vtable.GetValueAsUnsigned()
        expected_addr = self.expected_vtable_addr(rect)
        self.assertEqual(vtable_addr, expected_addr)

        for idx, vtable_entry in enumerate(vtable.children):
            self.verify_vtable_entry(vtable_entry, vtable_addr, idx)

    @skipIf(compiler="clang", compiler_version=["<", "9.0"])
    @skipUnlessPlatform(["linux", "macosx"])
    def test_base_class_ptr(self):
        self.build()
        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
            self, "Shape is Rectangle", lldb.SBFileSpec("main.cpp")
        )

        shape = self.frame().FindVariable("shape")
        rect = self.frame().FindVariable("rect")

        shape_ptr = self.frame().FindVariable("shape_ptr")
        shape_ptr_vtable = shape_ptr.GetVTable()
        self.assertEqual(shape_ptr_vtable.GetName(), "vtable for Rectangle")
        self.assertEqual(shape_ptr_vtable.GetNumChildren(), 5)
        self.assertEqual(shape_ptr.GetValueAsUnsigned(0), rect.GetLoadAddress())
        lldbutil.continue_to_source_breakpoint(
            self, process, "Shape is Shape", lldb.SBFileSpec("main.cpp")
        )
        self.assertEqual(shape_ptr.GetValueAsUnsigned(0), shape.GetLoadAddress())
        self.assertEqual(shape_ptr_vtable.GetNumChildren(), 4)
        self.assertEqual(shape_ptr_vtable.GetName(), "vtable for Shape")

    @skipUnlessPlatform(["linux", "macosx"])
    def test_no_vtable(self):
        self.build()
        lldbutil.run_to_source_breakpoint(
            self, "At the end", lldb.SBFileSpec("main.cpp")
        )

        var = self.frame().FindVariable("not_virtual")
        self.assertEqual(
            var.GetVTable().GetError().GetCString(),
            'type "NotVirtual" doesn\'t have a vtable',
        )

        var = self.frame().FindVariable("argc")
        self.assertEqual(
            var.GetVTable().GetError().GetCString(),
            'no language runtime support for the language "c"',
        )

    @skipUnlessPlatform(["linux", "macosx"])
    def test_overwrite_vtable(self):
        self.build()
        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
            self, "At the end", lldb.SBFileSpec("main.cpp")
        )

        # Test a shape instance to make sure we get the vtable correctly.
        shape = self.frame().FindVariable("shape")
        vtable = shape.GetVTable()
        self.assertEqual(vtable.GetName(), "vtable for Shape")
        self.assertEqual(vtable.GetTypeName(), "vtable for Shape")
        # Make sure we have the right number of virtual functions in our vtable
        # for the shape class.
        self.assertEqual(vtable.GetNumChildren(), 4)

        # Overwrite the first entry in the vtable and make sure we can still
        # see the bogus value which should have no summary
        vtable_addr = vtable.GetValueAsUnsigned()

        is_64bit = self.process().GetAddressByteSize() == 8
        data = str(
            "\x01\x01\x01\x01\x01\x01\x01\x01" if is_64bit else "\x01\x01\x01\x01"
        )
        error = lldb.SBError()
        process.WriteMemory(vtable_addr, data, error)

        scribbled_child = vtable.GetChildAtIndex(0)
        self.assertEqual(
            scribbled_child.GetValueAsUnsigned(0),
            0x0101010101010101 if is_64bit else 0x01010101,
        )
        self.assertEqual(scribbled_child.GetSummary(), None)

    def expected_vtable_addr(self, var: lldb.SBValue) -> int:
        load_addr = var.GetLoadAddress()
        read_from_memory_error = lldb.SBError()
        vtable_addr = self.process().ReadPointerFromMemory(
            load_addr, read_from_memory_error
        )
        self.assertTrue(read_from_memory_error.Success())
        return vtable_addr

    def expected_vtable_entry_func_ptr(self, vtable_addr: int, idx: int):
        vtable_entry_addr = vtable_addr + idx * self.process().GetAddressByteSize()
        read_func_ptr_error = lldb.SBError()
        func_ptr = self.process().ReadPointerFromMemory(
            vtable_entry_addr, read_func_ptr_error
        )
        self.assertTrue(read_func_ptr_error.Success())
        return func_ptr

    def verify_vtable_entry(
        self, vtable_entry: lldb.SBValue, vtable_addr: int, idx: int
    ):
        """Verify the vtable entry looks something like:

        (double ()) [0] = 0x0000000100003a10 a.out`Rectangle::Area() at main.cpp:14

        """
        # Check function ptr
        vtable_entry_func_ptr = vtable_entry.GetValueAsUnsigned(0)
        self.assertEqual(
            vtable_entry_func_ptr,
            self.expected_vtable_entry_func_ptr(vtable_addr, idx),
        )

        sb_addr = self.target().ResolveLoadAddress(vtable_entry_func_ptr)
        sym_ctx = sb_addr.GetSymbolContext(lldb.eSymbolContextEverything)

        # Make sure the type is the same as the function type
        func_type = sym_ctx.GetFunction().GetType()
        if func_type.IsValid():
            self.assertEqual(vtable_entry.GetType(), func_type.GetPointerType())

        # The summary should be the address description of the function pointer
        summary = vtable_entry.GetSummary()
        self.assertEqual(str(sb_addr), summary)
