"""
Test breakpoint serialization.
"""

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


class BreakpointSerialization(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    @add_test_categories(["pyapi"])
    def test_resolvers(self):
        """Use Python APIs to test that we serialize resolvers."""
        self.build()
        self.setup_targets_and_cleanup()
        self.do_check_resolvers()

    def test_filters(self):
        """Use Python APIs to test that we serialize search filters correctly."""
        self.build()
        self.setup_targets_and_cleanup()
        self.do_check_filters()

    def test_options(self):
        """Use Python APIs to test that we serialize breakpoint options correctly."""
        self.build()
        self.setup_targets_and_cleanup()
        self.do_check_options()

    def test_appending(self):
        """Use Python APIs to test that we serialize breakpoint options correctly."""
        self.build()
        self.setup_targets_and_cleanup()
        self.do_check_appending()

    def test_name_filters(self):
        """Use python APIs to test that reading in by name works correctly."""
        self.build()
        self.setup_targets_and_cleanup()
        self.do_check_names()

    def test_scripted_extra_args(self):
        self.build()
        self.setup_targets_and_cleanup()
        self.do_check_extra_args()

    def test_resolver_serialization(self):
        """Test that breakpoint resolvers contain the expected information"""
        self.build()
        self.setup_targets_and_cleanup()

        exe_path = self.getBuildArtifact("a.out")
        exe_module = self.orig_target.module["a.out"]
        self.assertTrue(
            exe_module.IsValid(), "Failed to find the executable module in target"
        )
        sym_ctx_list = exe_module.FindFunctions("main")
        self.assertEqual(sym_ctx_list.GetSize(), 1, "Unable to find function 'main'")
        sym_ctx = sym_ctx_list.GetContextAtIndex(0)
        self.assertTrue(
            sym_ctx.IsValid(), "SBSymbolContext representing function 'main' is invalid"
        )
        main_func = sym_ctx.GetFunction()
        self.assertTrue(
            main_func.IsValid(), "SBFunction representing 'main' is invalid"
        )
        main_addr = main_func.GetStartAddress()

        bkpt = self.orig_target.BreakpointCreateBySBAddress(main_addr)
        self.assertTrue(
            bkpt.IsValid(), "Could not place breakpoint on 'main' by address"
        )
        stream = lldb.SBStream()
        sd = bkpt.SerializeToStructuredData()
        sd.GetAsJSON(stream)
        serialized_data = json.loads(stream.GetData())

        self.assertIn(
            exe_path,
            serialized_data["Breakpoint"]["BKPTResolver"]["Options"]["ModuleName"],
        )

    def test_structured_data_serialization(self):
        target = self.dbg.GetDummyTarget()
        self.assertTrue(target.IsValid(), VALID_TARGET)

        interpreter = self.dbg.GetCommandInterpreter()
        result = lldb.SBCommandReturnObject()
        interpreter.HandleCommand("br set -f foo -l 42", result)
        result = lldb.SBCommandReturnObject()
        interpreter.HandleCommand("br set -c 'argc == 1' -n main", result)

        bkp1 = target.GetBreakpointAtIndex(0)
        self.assertTrue(bkp1.IsValid(), VALID_BREAKPOINT)
        stream = lldb.SBStream()
        sd = bkp1.SerializeToStructuredData()
        sd.GetAsJSON(stream)
        serialized_data = json.loads(stream.GetData())
        self.assertEqual(
            serialized_data["Breakpoint"]["BKPTResolver"]["Options"]["FileName"], "foo"
        )
        self.assertEqual(
            serialized_data["Breakpoint"]["BKPTResolver"]["Options"]["LineNumber"], 42
        )

        bkp2 = target.GetBreakpointAtIndex(1)
        self.assertTrue(bkp2.IsValid(), VALID_BREAKPOINT)
        stream = lldb.SBStream()
        sd = bkp2.SerializeToStructuredData()
        sd.GetAsJSON(stream)
        serialized_data = json.loads(stream.GetData())
        self.assertIn(
            "main",
            serialized_data["Breakpoint"]["BKPTResolver"]["Options"]["SymbolNames"],
        )
        self.assertEqual(
            serialized_data["Breakpoint"]["BKPTOptions"]["ConditionText"], "argc == 1"
        )

        invalid_bkp = lldb.SBBreakpoint()
        self.assertFalse(invalid_bkp.IsValid(), "Breakpoint should not be valid.")
        stream = lldb.SBStream()
        sd = invalid_bkp.SerializeToStructuredData()
        sd.GetAsJSON(stream)
        self.assertFalse(
            stream.GetData(), "Invalid breakpoint should have an empty structured data"
        )

    def setup_targets_and_cleanup(self):
        def cleanup():
            self.RemoveTempFile(self.bkpts_file_path)

            if self.orig_target.IsValid():
                self.dbg.DeleteTarget(self.orig_target)
                self.dbg.DeleteTarget(self.copy_target)

        self.addTearDownHook(cleanup)
        self.RemoveTempFile(self.bkpts_file_path)

        exe = self.getBuildArtifact("a.out")

        # Create the targets we are making breakpoints in and copying them to:
        self.orig_target = self.dbg.CreateTarget(exe)
        self.assertTrue(self.orig_target, VALID_TARGET)

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

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)

        self.bkpts_file_path = self.getBuildArtifact("breakpoints.json")
        self.bkpts_file_spec = lldb.SBFileSpec(self.bkpts_file_path)

    def check_equivalence(self, source_bps, do_write=True):
        error = lldb.SBError()

        if do_write:
            error = self.orig_target.BreakpointsWriteToFile(
                self.bkpts_file_spec, source_bps
            )
            self.assertSuccess(error, "Failed writing breakpoints to file")

        copy_bps = lldb.SBBreakpointList(self.copy_target)
        error = self.copy_target.BreakpointsCreateFromFile(
            self.bkpts_file_spec, copy_bps
        )
        self.assertSuccess(error, "Failed reading breakpoints from file")

        num_source_bps = source_bps.GetSize()
        num_copy_bps = copy_bps.GetSize()
        self.assertEqual(
            num_source_bps,
            num_copy_bps,
            "Didn't get same number of input and output breakpoints - orig: %d copy: %d"
            % (num_source_bps, num_copy_bps),
        )

        for i in range(0, num_source_bps):
            source_bp = source_bps.GetBreakpointAtIndex(i)
            source_desc = lldb.SBStream()
            source_bp.GetDescription(source_desc, False)
            source_text = source_desc.GetData()

            # I am assuming here that the breakpoints will get written out in breakpoint ID order, and
            # read back in ditto.  That is true right now, and I can't see any reason to do it differently
            # but if we do we can go to writing the breakpoints one by one, or sniffing the descriptions to
            # see which one is which.
            copy_id = source_bp.GetID()
            copy_bp = copy_bps.FindBreakpointByID(copy_id)
            self.assertTrue(
                copy_bp.IsValid(), "Could not find copy breakpoint %d." % (copy_id)
            )

            copy_desc = lldb.SBStream()
            copy_bp.GetDescription(copy_desc, False)
            copy_text = copy_desc.GetData()

            # These two should be identical.
            self.trace("Source text for %d is %s." % (i, source_text))
            self.assertEqual(
                source_text,
                copy_text,
                "Source and dest breakpoints are not identical: \nsource: %s\ndest: %s"
                % (source_text, copy_text),
            )

    def do_check_resolvers(self):
        """Use Python APIs to check serialization of breakpoint resolvers"""

        empty_module_list = lldb.SBFileSpecList()
        empty_cu_list = lldb.SBFileSpecList()
        blubby_file_spec = lldb.SBFileSpec(
            os.path.join(self.getSourceDir(), "blubby.c")
        )

        # It isn't actually important for these purposes that these breakpoint
        # actually have locations.
        source_bps = lldb.SBBreakpointList(self.orig_target)
        source_bps.Append(self.orig_target.BreakpointCreateByLocation("blubby.c", 666))
        # Make sure we do one breakpoint right:
        self.check_equivalence(source_bps)
        source_bps.Clear()

        source_bps.Append(
            self.orig_target.BreakpointCreateByName(
                "blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list
            )
        )
        source_bps.Append(
            self.orig_target.BreakpointCreateByName(
                "blubby", lldb.eFunctionNameTypeFull, empty_module_list, empty_cu_list
            )
        )
        source_bps.Append(
            self.orig_target.BreakpointCreateBySourceRegex(
                "dont really care", blubby_file_spec
            )
        )

        # And some number greater than one:
        self.check_equivalence(source_bps)

    def do_check_filters(self):
        """Use Python APIs to check serialization of breakpoint filters."""
        module_list = lldb.SBFileSpecList()
        module_list.Append(lldb.SBFileSpec("SomeBinary"))
        module_list.Append(lldb.SBFileSpec("SomeOtherBinary"))

        cu_list = lldb.SBFileSpecList()
        cu_list.Append(lldb.SBFileSpec("SomeCU.c"))
        cu_list.Append(lldb.SBFileSpec("AnotherCU.c"))
        cu_list.Append(lldb.SBFileSpec("ThirdCU.c"))

        blubby_file_spec = lldb.SBFileSpec(
            os.path.join(self.getSourceDir(), "blubby.c")
        )

        # It isn't actually important for these purposes that these breakpoint
        # actually have locations.
        source_bps = lldb.SBBreakpointList(self.orig_target)
        bkpt = self.orig_target.BreakpointCreateByLocation(
            blubby_file_spec, 666, 0, module_list
        )
        source_bps.Append(bkpt)

        # Make sure we do one right:
        self.check_equivalence(source_bps)
        source_bps.Clear()

        bkpt = self.orig_target.BreakpointCreateByName(
            "blubby", lldb.eFunctionNameTypeAuto, module_list, cu_list
        )
        source_bps.Append(bkpt)
        bkpt = self.orig_target.BreakpointCreateByName(
            "blubby", lldb.eFunctionNameTypeFull, module_list, cu_list
        )
        source_bps.Append(bkpt)
        bkpt = self.orig_target.BreakpointCreateBySourceRegex(
            "dont really care", blubby_file_spec
        )
        source_bps.Append(bkpt)

        # And some number greater than one:
        self.check_equivalence(source_bps)

    def do_check_options(self):
        """Use Python APIs to check serialization of breakpoint options."""

        empty_module_list = lldb.SBFileSpecList()
        empty_cu_list = lldb.SBFileSpecList()
        blubby_file_spec = lldb.SBFileSpec(
            os.path.join(self.getSourceDir(), "blubby.c")
        )

        # It isn't actually important for these purposes that these breakpoint
        # actually have locations.
        source_bps = lldb.SBBreakpointList(self.orig_target)

        bkpt = self.orig_target.BreakpointCreateByLocation(
            lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList()
        )
        bkpt.SetEnabled(False)
        bkpt.SetOneShot(True)
        bkpt.SetThreadID(10)
        source_bps.Append(bkpt)

        # Make sure we get one right:
        self.check_equivalence(source_bps)
        source_bps.Clear()

        bkpt = self.orig_target.BreakpointCreateByName(
            "blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list
        )
        bkpt.SetIgnoreCount(10)
        bkpt.SetThreadName("grubby")
        source_bps.Append(bkpt)

        bkpt = self.orig_target.BreakpointCreateByName(
            "blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list
        )
        bkpt.SetCondition("gonna remove this")
        bkpt.SetCondition("")
        source_bps.Append(bkpt)

        bkpt = self.orig_target.BreakpointCreateByName(
            "blubby", lldb.eFunctionNameTypeFull, empty_module_list, empty_cu_list
        )
        bkpt.SetCondition("something != something_else")
        bkpt.SetQueueName("grubby")
        bkpt.AddName("FirstName")
        bkpt.AddName("SecondName")
        bkpt.SetScriptCallbackBody(
            '\tprint("I am a function that prints.")\n\tprint("I don\'t do anything else")\n'
        )
        source_bps.Append(bkpt)

        bkpt = self.orig_target.BreakpointCreateBySourceRegex(
            "dont really care", blubby_file_spec
        )
        cmd_list = lldb.SBStringList()
        cmd_list.AppendString("frame var")
        cmd_list.AppendString("thread backtrace")

        bkpt.SetCommandLineCommands(cmd_list)
        source_bps.Append(bkpt)

        self.check_equivalence(source_bps)

    def do_check_appending(self):
        """Use Python APIs to check appending to already serialized options."""

        empty_module_list = lldb.SBFileSpecList()
        empty_cu_list = lldb.SBFileSpecList()
        blubby_file_spec = lldb.SBFileSpec(
            os.path.join(self.getSourceDir(), "blubby.c")
        )

        # It isn't actually important for these purposes that these breakpoint
        # actually have locations.

        all_bps = lldb.SBBreakpointList(self.orig_target)
        source_bps = lldb.SBBreakpointList(self.orig_target)

        bkpt = self.orig_target.BreakpointCreateByLocation(
            lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList()
        )
        bkpt.SetEnabled(False)
        bkpt.SetOneShot(True)
        bkpt.SetThreadID(10)
        source_bps.Append(bkpt)
        all_bps.Append(bkpt)

        error = lldb.SBError()
        error = self.orig_target.BreakpointsWriteToFile(
            self.bkpts_file_spec, source_bps
        )
        self.assertSuccess(error, "Failed writing breakpoints to file")

        source_bps.Clear()

        bkpt = self.orig_target.BreakpointCreateByName(
            "blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list
        )
        bkpt.SetIgnoreCount(10)
        bkpt.SetThreadName("grubby")
        source_bps.Append(bkpt)
        all_bps.Append(bkpt)

        bkpt = self.orig_target.BreakpointCreateByName(
            "blubby", lldb.eFunctionNameTypeFull, empty_module_list, empty_cu_list
        )
        bkpt.SetCondition("something != something_else")
        bkpt.SetQueueName("grubby")
        bkpt.AddName("FirstName")
        bkpt.AddName("SecondName")

        source_bps.Append(bkpt)
        all_bps.Append(bkpt)

        error = self.orig_target.BreakpointsWriteToFile(
            self.bkpts_file_spec, source_bps, True
        )
        self.assertSuccess(error, "Failed appending breakpoints to file")

        self.check_equivalence(all_bps)

    def do_check_names(self):
        bkpt = self.orig_target.BreakpointCreateByLocation(
            lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList()
        )
        good_bkpt_name = "GoodBreakpoint"
        write_bps = lldb.SBBreakpointList(self.orig_target)
        bkpt.AddName(good_bkpt_name)
        write_bps.Append(bkpt)

        error = lldb.SBError()
        error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps)
        self.assertSuccess(error, "Failed writing breakpoints to file")

        copy_bps = lldb.SBBreakpointList(self.copy_target)
        names_list = lldb.SBStringList()
        names_list.AppendString("NoSuchName")

        error = self.copy_target.BreakpointsCreateFromFile(
            self.bkpts_file_spec, names_list, copy_bps
        )
        self.assertSuccess(error, "Failed reading breakpoints from file")
        self.assertEqual(
            copy_bps.GetSize(), 0, "Found breakpoints with a nonexistent name."
        )

        names_list.AppendString(good_bkpt_name)
        error = self.copy_target.BreakpointsCreateFromFile(
            self.bkpts_file_spec, names_list, copy_bps
        )
        self.assertSuccess(error, "Failed reading breakpoints from file")
        self.assertEqual(copy_bps.GetSize(), 1, "Found the matching breakpoint.")

    def do_check_extra_args(self):
        import side_effect

        interp = self.dbg.GetCommandInterpreter()
        error = lldb.SBError()

        script_name = os.path.join(self.getSourceDir(), "resolver.py")

        command = "command script import " + script_name
        result = lldb.SBCommandReturnObject()
        interp.HandleCommand(command, result)
        self.assertTrue(
            result.Succeeded(), "com scr imp failed: %s" % (result.GetError())
        )

        # First make sure a scripted breakpoint with no args works:
        bkpt = self.orig_target.BreakpointCreateFromScript(
            "resolver.Resolver",
            lldb.SBStructuredData(),
            lldb.SBFileSpecList(),
            lldb.SBFileSpecList(),
        )
        self.assertTrue(bkpt.IsValid(), "Bkpt is valid")
        write_bps = lldb.SBBreakpointList(self.orig_target)

        error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps)
        self.assertSuccess(error, "Failed writing breakpoints")

        side_effect.g_extra_args = None
        copy_bps = lldb.SBBreakpointList(self.copy_target)
        error = self.copy_target.BreakpointsCreateFromFile(
            self.bkpts_file_spec, copy_bps
        )
        self.assertSuccess(error, "Failed reading breakpoints")

        self.assertEqual(copy_bps.GetSize(), 1, "Got one breakpoint from file.")
        no_keys = lldb.SBStringList()
        side_effect.g_extra_args.GetKeys(no_keys)
        self.assertEqual(no_keys.GetSize(), 0, "Should have no keys")

        self.orig_target.DeleteAllBreakpoints()
        self.copy_target.DeleteAllBreakpoints()

        # Now try one with extra args:

        extra_args = lldb.SBStructuredData()
        stream = lldb.SBStream()
        stream.Print('{"first_arg" : "first_value", "second_arg" : "second_value"}')
        extra_args.SetFromJSON(stream)
        self.assertTrue(extra_args.IsValid(), "SBStructuredData is valid.")

        bkpt = self.orig_target.BreakpointCreateFromScript(
            "resolver.Resolver",
            extra_args,
            lldb.SBFileSpecList(),
            lldb.SBFileSpecList(),
        )
        self.assertTrue(bkpt.IsValid(), "Bkpt is valid")
        write_bps = lldb.SBBreakpointList(self.orig_target)

        error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps)
        self.assertSuccess(error, "Failed writing breakpoints")

        orig_extra_args = side_effect.g_extra_args
        self.assertTrue(orig_extra_args.IsValid(), "Extra args originally valid")

        orig_keys = lldb.SBStringList()
        orig_extra_args.GetKeys(orig_keys)
        self.assertEqual(2, orig_keys.GetSize(), "Should have two keys")

        side_effect.g_extra_args = None

        copy_bps = lldb.SBBreakpointList(self.copy_target)
        error = self.copy_target.BreakpointsCreateFromFile(
            self.bkpts_file_spec, copy_bps
        )
        self.assertSuccess(error, "Failed reading breakpoints")

        self.assertEqual(copy_bps.GetSize(), 1, "Got one breakpoint from file.")

        copy_extra_args = side_effect.g_extra_args
        copy_keys = lldb.SBStringList()
        copy_extra_args.GetKeys(copy_keys)
        self.assertEqual(2, copy_keys.GetSize(), "Copy should have two keys")

        for idx in range(0, orig_keys.GetSize()):
            key = orig_keys.GetStringAtIndex(idx)
            copy_value = copy_extra_args.GetValueForKey(key).GetStringValue(100)

            if key == "first_arg":
                self.assertEqual(copy_value, "first_value")
            elif key == "second_arg":
                self.assertEqual(copy_value, "second_value")
            else:
                self.Fail("Unknown key: %s" % (key))
