"""
Test lldb core component: SourceManager.

Test cases:

o test_display_source_python:
  Test display of source using the SBSourceManager API.
o test_modify_source_file_while_debugging:
  Test the caching mechanism of the source manager.
"""

import os
import io
import stat

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


def ansi_underline_surround_regex(inner_regex_text):
    # return re.compile(r"\[4m%s\[0m" % inner_regex_text)
    return "4.+\033\\[4m%s\033\\[0m" % inner_regex_text


def ansi_color_surround_regex(inner_regex_text):
    return "\033\\[3[0-7]m%s\033\\[0m" % inner_regex_text


class SourceManagerTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line number to break inside main().
        self.file = self.getBuildArtifact("main-copy.c")
        self.line = line_number("main.c", "// Set break point at this line.")

    def modify_content(self):
        # Read the main.c file content.
        with io.open(self.file, "r", newline="\n") as f:
            original_content = f.read()
            if self.TraceOn():
                print("original content:", original_content)

        # Modify the in-memory copy of the original source code.
        new_content = original_content.replace("Hello world", "Hello lldb", 1)

        # Modify the source code file.
        # If the source was read only, the copy will also be read only.
        # Run "chmod u+w" on it first so we can modify it.
        statinfo = os.stat(self.file)
        os.chmod(self.file, statinfo.st_mode | stat.S_IWUSR)

        with io.open(self.file, "w", newline="\n") as f:
            time.sleep(1)
            f.write(new_content)
            if self.TraceOn():
                print("new content:", new_content)
                print(
                    "os.path.getmtime() after writing new content:",
                    os.path.getmtime(self.file),
                )

    def get_expected_stop_column_number(self):
        """Return the 1-based column number of the first non-whitespace
        character in the breakpoint source line."""
        stop_line = get_line(self.file, self.line)
        # The number of spaces that must be skipped to get to the first non-
        # whitespace character --- where we expect the debugger breakpoint
        # column to be --- is equal to the number of characters that get
        # stripped off the front when we lstrip it, plus one to specify
        # the character column after the initial whitespace.
        return len(stop_line) - len(stop_line.lstrip()) + 1

    def do_display_source_python_api(
        self, use_color, needle_regex, highlight_source=False
    ):
        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 do not stop at the entry point.
        args = None
        envp = None
        process = target.LaunchSimple(args, envp, self.get_process_working_directory())
        self.assertIsNotNone(process)

        #
        # Exercise Python APIs to display source lines.
        #

        # Setup whether we should use ansi escape sequences, including color
        # and styles such as underline.
        self.dbg.SetUseColor(use_color)
        # Disable syntax highlighting if needed.

        self.runCmd("settings set highlight-source " + str(highlight_source).lower())

        filespec = lldb.SBFileSpec(self.file, False)
        source_mgr = self.dbg.GetSourceManager()
        # Use a string stream as the destination.
        stream = lldb.SBStream()
        column = self.get_expected_stop_column_number()
        context_before = 2
        context_after = 2
        current_line_prefix = "=>"
        source_mgr.DisplaySourceLinesWithLineNumbersAndColumn(
            filespec,
            self.line,
            column,
            context_before,
            context_after,
            current_line_prefix,
            stream,
        )

        #    2
        #    3    int main(int argc, char const *argv[]) {
        # => 4        printf("Hello world.\n"); // Set break point at this line.
        #    5        return 0;
        #    6    }
        self.expect(
            stream.GetData(),
            "Source code displayed correctly:\n" + stream.GetData(),
            exe=False,
            patterns=["=>", "%d.*Hello world" % self.line, needle_regex],
        )

        # Boundary condition testings for SBStream().  LLDB should not crash!
        stream.Print(None)
        stream.RedirectToFile(None, True)

    @add_test_categories(["pyapi"])
    def test_display_source_python_dumb_terminal(self):
        """Test display of source using the SBSourceManager API, using a
        dumb terminal and thus no color support (the default)."""
        use_color = False
        self.do_display_source_python_api(use_color, r"\s+\^")

    @add_test_categories(["pyapi"])
    def test_display_source_python_ansi_terminal(self):
        """Test display of source using the SBSourceManager API, using a
        dumb terminal and thus no color support (the default)."""
        use_color = True
        underline_regex = ansi_underline_surround_regex(r"printf")
        self.do_display_source_python_api(use_color, underline_regex)

    @add_test_categories(["pyapi"])
    def test_display_source_python_ansi_terminal_syntax_highlighting(self):
        """Test display of source using the SBSourceManager API and check for
        the syntax highlighted output"""
        use_color = True
        syntax_highlighting = True

        # Just pick 'int' as something that should be colored.
        color_regex = ansi_color_surround_regex("int")
        self.do_display_source_python_api(use_color, color_regex, syntax_highlighting)

        # Same for 'char'.
        color_regex = ansi_color_surround_regex("char")
        self.do_display_source_python_api(use_color, color_regex, syntax_highlighting)

        # Test that we didn't color unrelated identifiers.
        self.do_display_source_python_api(use_color, r" main\(", syntax_highlighting)
        self.do_display_source_python_api(use_color, r"\);", syntax_highlighting)

    def test_move_and_then_display_source(self):
        """Test that target.source-map settings work by moving main.c to hidden/main.c."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        # Move main.c to hidden/main.c.
        hidden = self.getBuildArtifact("hidden")
        lldbutil.mkdir_p(hidden)
        main_c_hidden = os.path.join(hidden, "main-copy.c")
        os.rename(self.file, main_c_hidden)

        # Set source remapping with invalid replace path and verify we get an
        # error
        self.expect(
            "settings set target.source-map /a/b/c/d/e /q/r/s/t/u",
            error=True,
            substrs=['''error: the replacement path doesn't exist: "/q/r/s/t/u"'''],
        )

        # 'make -C' has resolved current directory to its realpath form.
        builddir_real = os.path.realpath(self.getBuildDir())
        hidden_real = os.path.realpath(hidden)
        # Set target.source-map settings.
        self.runCmd(
            "settings set target.source-map %s %s" % (builddir_real, hidden_real)
        )
        # And verify that the settings work.
        self.expect(
            "settings show target.source-map", substrs=[builddir_real, hidden_real]
        )

        # Display main() and verify that the source mapping has been kicked in.
        self.expect(
            "source list -n main", SOURCE_DISPLAYED_CORRECTLY, substrs=["Hello world"]
        )

    @skipIf(oslist=["windows"], bugnumber="llvm.org/pr44431")
    def test_modify_source_file_while_debugging(self):
        """Modify a source file while debugging the executable."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        lldbutil.run_break_set_by_file_and_line(
            self, "main-copy.c", self.line, num_expected_locations=1, loc_exact=True
        )

        self.runCmd("run", RUN_SUCCEEDED)

        # The stop reason of the thread should be breakpoint.
        self.expect(
            "thread list",
            STOPPED_DUE_TO_BREAKPOINT,
            substrs=[
                "stopped",
                "main-copy.c:%d" % self.line,
                "stop reason = breakpoint",
            ],
        )

        # Display some source code.
        self.expect(
            "source list -f main-copy.c -l %d" % self.line,
            SOURCE_DISPLAYED_CORRECTLY,
            substrs=["Hello world"],
        )

        # Do the same thing with a file & line spec:
        self.expect(
            "source list -y main-copy.c:%d" % self.line,
            SOURCE_DISPLAYED_CORRECTLY,
            substrs=["Hello world"],
        )

        # The '-b' option shows the line table locations from the debug information
        # that indicates valid places to set source level breakpoints.

        # The file to display is implicit in this case.
        self.runCmd("source list -l %d -c 3 -b" % self.line)
        output = self.res.GetOutput().splitlines()[0]

        # If the breakpoint set command succeeded, we should expect a positive number
        # of breakpoints for the current line, i.e., self.line.
        import re

        m = re.search("^\[(\d+)\].*// Set break point at this line.", output)
        if not m:
            self.fail("Fail to display source level breakpoints")
        self.assertGreater(int(m.group(1)), 0)

        # Modify content
        self.modify_content()

        # Display the source code again. We should not see the updated line.
        self.expect(
            "source list -f main-copy.c -l %d" % self.line,
            SOURCE_DISPLAYED_CORRECTLY,
            substrs=["Hello world"],
        )

        # clear the source cache.
        self.runCmd("source cache clear")

        # Display the source code again. Now we should see the updated line.
        self.expect(
            "source list -f main-copy.c -l %d" % self.line,
            SOURCE_DISPLAYED_CORRECTLY,
            substrs=["Hello lldb"],
        )

    def test_set_breakpoint_with_absolute_path(self):
        self.build()
        hidden = self.getBuildArtifact("hidden")
        lldbutil.mkdir_p(hidden)
        # 'make -C' has resolved current directory to its realpath form.
        builddir_real = os.path.realpath(self.getBuildDir())
        hidden_real = os.path.realpath(hidden)
        self.runCmd(
            "settings set target.source-map %s %s" % (builddir_real, hidden_real)
        )

        exe = self.getBuildArtifact("a.out")
        main = os.path.join(builddir_real, "hidden", "main-copy.c")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        lldbutil.run_break_set_by_file_and_line(
            self, main, self.line, num_expected_locations=1, loc_exact=False
        )

        self.runCmd("run", RUN_SUCCEEDED)

        # The stop reason of the thread should be breakpoint.
        self.expect(
            "thread list",
            STOPPED_DUE_TO_BREAKPOINT,
            substrs=[
                "stopped",
                "main-copy.c:%d" % self.line,
                "stop reason = breakpoint",
            ],
        )

    def test_artificial_source_location(self):
        src_file = "artificial_location.c"
        d = {"C_SOURCES": src_file}
        self.build(dictionary=d)

        lldbutil.run_to_source_breakpoint(
            self, "main", lldb.SBFileSpec(src_file, False)
        )

        self.expect(
            "process status",
            substrs=[
                "stop reason = breakpoint",
                f"{src_file}:0",
                "Note: this address is compiler-generated code in function",
                "that has no source code associated with it.",
            ],
        )

    def test_source_cache_dump_and_clear(self):
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
        lldbutil.run_break_set_by_file_and_line(
            self, self.file, self.line, num_expected_locations=1, loc_exact=True
        )
        self.runCmd("run", RUN_SUCCEEDED)

        # Make sure the main source file is in the source cache.
        self.expect(
            "source cache dump",
            substrs=["Modification time", "Lines", "Path", " 7", self.file],
        )

        # Clear the cache.
        self.expect("source cache clear")

        # Make sure the main source file is no longer in the source cache.
        self.expect("source cache dump", matching=False, substrs=[self.file])

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

        # Create a first target.
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
        lldbutil.run_break_set_by_symbol(self, "main", num_expected_locations=1)
        self.expect("run", RUN_SUCCEEDED, substrs=["Hello world"])

        # Create a second target.
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
        lldbutil.run_break_set_by_symbol(self, "main", num_expected_locations=1)
        self.expect("run", RUN_SUCCEEDED, substrs=["Hello world"])

        # Modify the source file content.
        self.modify_content()

        # Clear the source cache. This will wipe the debugger and the process
        # cache for the second process.
        self.runCmd("source cache clear")

        # Make sure we're seeing the new content from the clean process cache.
        self.expect(
            "next",
            SOURCE_DISPLAYED_CORRECTLY,
            substrs=["Hello lldb"],
        )

        # Switch back to the first target.
        self.runCmd("target select 0")

        # Make sure we're seeing the old content from the first target's
        # process cache.
        self.expect(
            "next",
            SOURCE_DISPLAYED_CORRECTLY,
            substrs=["Hello world"],
        )
