"""
Make sure the frame variable -g, -a, and -l flags work.
"""

import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import os
import shutil
import time


class TestFrameVar(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

    def test_frame_var(self):
        self.build()
        self.do_test()

    def do_test(self):
        target = self.createTestTarget()

        # Now create a breakpoint in main.c at the source matching
        # "Set a breakpoint here"
        breakpoint = target.BreakpointCreateBySourceRegex(
            "Set a breakpoint here", lldb.SBFileSpec("main.c")
        )
        self.assertTrue(
            breakpoint and breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT
        )

        error = lldb.SBError()
        # This is the launch info.  If you want to launch with arguments or
        # environment variables, add them using SetArguments or
        # SetEnvironmentEntries

        launch_info = target.GetLaunchInfo()
        process = target.Launch(launch_info, error)
        self.assertTrue(process, PROCESS_IS_VALID)

        # Did we hit our breakpoint?
        from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint

        threads = get_threads_stopped_at_breakpoint(process, breakpoint)
        self.assertEqual(
            len(threads), 1, "There should be a thread stopped at our breakpoint"
        )

        # The hit count for the breakpoint should be 1.
        self.assertEqual(breakpoint.GetHitCount(), 1)

        frame = threads[0].GetFrameAtIndex(0)
        command_result = lldb.SBCommandReturnObject()
        interp = self.dbg.GetCommandInterpreter()

        # Ensure --regex can find globals if it is the very first frame var command.
        self.expect("frame var --regex g_", substrs=["g_var"])

        # Ensure the requested scope is respected:
        self.expect(
            "frame var --regex argc --no-args",
            error=True,
            substrs=["no variables matched the regular expression 'argc'"],
        )

        # Just get args:
        result = interp.HandleCommand("frame var -l", command_result)
        self.assertEqual(
            result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed"
        )
        output = command_result.GetOutput()
        self.assertIn("argc", output, "Args didn't find argc")
        self.assertIn("argv", output, "Args didn't find argv")
        self.assertNotIn("test_var", output, "Args found a local")
        self.assertNotIn("g_var", output, "Args found a global")

        value_list = command_result.GetValues(lldb.eNoDynamicValues)
        self.assertGreaterEqual(value_list.GetSize(), 2)
        value_names = []
        for value in value_list:
            value_names.append(value.GetName())
        self.assertIn("argc", value_names)
        self.assertIn("argv", value_names)

        # Just get locals:
        result = interp.HandleCommand("frame var -a", command_result)
        self.assertEqual(
            result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed"
        )
        output = command_result.GetOutput()
        self.assertNotIn("argc", output, "Locals found argc")
        self.assertNotIn("argv", output, "Locals found argv")
        self.assertIn("test_var", output, "Locals didn't find test_var")
        self.assertNotIn("g_var", output, "Locals found a global")

        # Get the file statics:
        result = interp.HandleCommand("frame var -l -a -g", command_result)
        self.assertEqual(
            result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed"
        )
        output = command_result.GetOutput()
        self.assertNotIn("argc", output, "Globals found argc")
        self.assertNotIn("argv", output, "Globals found argv")
        self.assertNotIn("test_var", output, "Globals found test_var")
        self.assertIn("g_var", output, "Globals didn't find g_var")

    def check_frame_variable_errors(self, thread, error_strings):
        command_result = lldb.SBCommandReturnObject()
        interp = self.dbg.GetCommandInterpreter()
        result = interp.HandleCommand("frame variable", command_result)
        self.assertEqual(
            result, lldb.eReturnStatusFailed, "frame var succeeded unexpectedly"
        )
        command_error = command_result.GetError()

        frame = thread.GetFrameAtIndex(0)
        var_list = frame.GetVariables(True, True, False, True)
        self.assertEqual(var_list.GetSize(), 0)
        api_error = var_list.GetError()
        api_error_str = api_error.GetCString()

        for s in error_strings:
            self.assertIn(s, command_error)
        for s in error_strings:
            self.assertIn(s, api_error_str)

        # Check the structured error data.
        data = api_error.GetErrorData()
        version = data.GetValueForKey("version")
        self.assertEqual(version.GetIntegerValue(), 1)
        err_ty = data.GetValueForKey("type")
        self.assertEqual(err_ty.GetIntegerValue(), lldb.eErrorTypeGeneric)
        message = str(data.GetValueForKey("errors").GetItemAtIndex(0))
        for s in error_strings:
            self.assertIn(s, message)

    @skipIfRemote
    @skipUnlessDarwin
    def test_darwin_dwarf_missing_obj(self):
        """
        Test that if we build a binary with DWARF in .o files and we remove
        the .o file for main.cpp, that we get an appropriate error when we
        do 'frame variable' that explains why we aren't seeing variables.
        """
        self.build(debug_info="dwarf")
        exe = self.getBuildArtifact("a.out")
        main_obj = self.getBuildArtifact("main.o")
        # Delete the main.o file that contains the debug info so we force an
        # error when we run to main and try to get variables
        os.unlink(main_obj)

        # We have to set a named breakpoint because we don't have any debug info
        # because we deleted the main.o file.
        (target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")
        error_strings = [
            'debug map object file "',
            'main.o" containing debug info does not exist, debug info will not be loaded',
        ]
        self.check_frame_variable_errors(thread, error_strings)

    @skipIfRemote
    @skipUnlessDarwin
    def test_darwin_dwarf_obj_mod_time_mismatch(self):
        """
        Test that if we build a binary with DWARF in .o files and we update
        the mod time of the .o file for main.cpp, that we get an appropriate
        error when we do 'frame variable' that explains why we aren't seeing
        variables.
        """
        self.build(debug_info="dwarf")
        exe = self.getBuildArtifact("a.out")
        main_obj = self.getBuildArtifact("main.o")

        # Set the modification time for main.o file to the current time after
        # sleeping for 2 seconds. This ensures the modification time will have
        # changed and will not match the modification time in the debug map and
        # force an error when we run to main and try to get variables
        time.sleep(2)
        os.utime(main_obj, None)

        # We have to set a named breakpoint because we don't have any debug info
        # because we deleted the main.o file since the mod times don't match
        # and debug info won't be loaded
        (target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")

        error_strings = [
            'debug map object file "',
            'main.o" changed (actual: 0x',
            ", debug map: 0x",
            ") since this executable was linked, debug info will not be loaded",
        ]
        self.check_frame_variable_errors(thread, error_strings)

    @skipIfRemote
    @skipIfWindows  # Windows can't set breakpoints by name 'main' in this case.
    def test_gline_tables_only(self):
        """
        Test that if we build a binary with "-gline-tables-only" that we can
        set a file and line breakpoint successfully, and get an error
        letting us know that this build option was enabled when trying to
        read variables.
        """
        self.build(dictionary={"CFLAGS_EXTRAS": "-gline-tables-only"})
        exe = self.getBuildArtifact("a.out")

        # We have to set a named breakpoint because we don't have any debug info
        # because we deleted the main.o file since the mod times don't match
        # and debug info won't be loaded
        (target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")
        error_strings = [
            "no variable information is available in debug info for this compile unit"
        ]
        self.check_frame_variable_errors(thread, error_strings)

    @skipUnlessPlatform(["linux", "freebsd"])
    @add_test_categories(["dwo"])
    def test_fission_missing_dwo(self):
        """
        Test that if we build a binary with "-gsplit-dwarf" that we can
        set a file and line breakpoint successfully, and get an error
        letting us know we were unable to load the .dwo file.
        """
        self.build(dictionary={"CFLAGS_EXTRAS": "-gsplit-dwarf"})
        exe = self.getBuildArtifact("a.out")
        main_dwo = self.getBuildArtifact("main.dwo")

        self.assertTrue(
            os.path.exists(main_dwo), 'Make sure "%s" file exists' % (main_dwo)
        )
        # Delete the main.dwo file that contains the debug info so we force an
        # error when we run to main and try to get variables.
        os.unlink(main_dwo)

        # We have to set a named breakpoint because we don't have any debug info
        # because we deleted the main.o file since the mod times don't match
        # and debug info won't be loaded
        (target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")
        error_strings = [
            'unable to locate .dwo debug file "',
            'main.dwo" for skeleton DIE 0x',
        ]
        self.check_frame_variable_errors(thread, error_strings)

    @skipUnlessPlatform(["linux", "freebsd"])
    @add_test_categories(["dwo"])
    def test_fission_invalid_dwo_objectfile(self):
        """
        Test that if we build a binary with "-gsplit-dwarf" that we can
        set a file and line breakpoint successfully, and get an error
        letting us know we were unable to load the .dwo file because it
        existed, but it wasn't a valid object file.
        """
        self.build(dictionary={"CFLAGS_EXTRAS": "-gsplit-dwarf"})
        exe = self.getBuildArtifact("a.out")
        main_dwo = self.getBuildArtifact("main.dwo")

        self.assertTrue(
            os.path.exists(main_dwo), 'Make sure "%s" file exists' % (main_dwo)
        )
        # Overwrite the main.dwo with the main.c source file so that the .dwo
        # file exists, but it isn't a valid object file as there is an error
        # for this case.
        shutil.copyfile(self.getSourcePath("main.c"), main_dwo)

        # We have to set a named breakpoint because we don't have any debug info
        # because we deleted the main.o file since the mod times don't match
        # and debug info won't be loaded
        (target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")
        error_strings = [
            'unable to load object file for .dwo debug file "'
            'main.dwo" for unit DIE 0x',
        ]
        self.check_frame_variable_errors(thread, error_strings)
