"""
Test setting a breakpoint by line and column.
"""

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


class BreakpointByLineAndColumnTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info
    @skipIf(compiler="gcc", compiler_version=['<', '7.1'])
    def testBreakpointByLineAndColumn(self):
        self.build()
        src_file = lldb.SBFileSpec("main.cpp")
        line = line_number("main.cpp",
                           "At the beginning of a function name (col:50)") + 1 # Next line after comment
        _, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self,
                                                              src_file, line, 50)
        self.expect("fr v did_call", substrs=['1'])
        in_then = False
        for i in range(breakpoint.GetNumLocations()):
            b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry()
            self.assertEqual(b_loc.GetLine(), line)
            in_then |= b_loc.GetColumn() == 50
        self.assertTrue(in_then)

    ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info
    @skipIf(compiler="gcc", compiler_version=['<', '7.1'])
    def testBreakpointByLine(self):
        self.build()
        src_file = lldb.SBFileSpec("main.cpp")
        line = line_number("main.cpp",
                           "At the beginning of a function name (col:50)") + 1 # Next line after comment
        _, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self, src_file,
                                                              line)
        self.expect("fr v did_call", substrs=['0'])
        in_condition = False
        for i in range(breakpoint.GetNumLocations()):
            b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry()
            self.assertEqual(b_loc.GetLine(), line)
            in_condition |= b_loc.GetColumn() < 30
        self.assertTrue(in_condition)

    ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info
    @skipIf(compiler="gcc", compiler_version=['<', '7.1'])
    def testBreakpointByLineAndColumnNearestCode(self):
        self.build()
        exe = self.getBuildArtifact("a.out")

        patterns = [
            "In the middle of a function name (col:42)",
            "In the middle of the lambda declaration argument (col:23)",
            "Inside the lambda (col:26)"
        ]

        source_loc = []

        for pattern in patterns:
            line = line_number("main.cpp", pattern) + 1
            column = int(re.search('\(col:([0-9]+)\)', pattern).group(1))
            source_loc.append({'line':line, 'column':column})

        # Create a target from the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)


        for loc in source_loc:
            src_file = lldb.SBFileSpec("main.cpp")
            line = loc['line']
            column = loc['column']
            indent = 0
            module_list = lldb.SBFileSpecList()

            valid_bpkt = target.BreakpointCreateByLocation(src_file, line,
                                                          column, indent,
                                                          module_list, True)
            self.assertTrue(valid_bpkt, VALID_BREAKPOINT)
            self.assertEqual(valid_bpkt.GetNumLocations(), 1)

        process = target.LaunchSimple(
                            None, None, self.get_process_working_directory())
        self.assertTrue(process, PROCESS_IS_VALID)

        nearest_column = [7, 17, 26]

        for idx,loc in enumerate(source_loc):
            bpkt = target.GetBreakpointAtIndex(idx)
            bpkt_loc = bpkt.GetLocationAtIndex(0)
            self.assertEqual(bpkt_loc.GetHitCount(), 1)
            self.assertSuccess(process.Continue())
            bpkt_loc_desc = lldb.SBStream()
            self.assertTrue(bpkt_loc.GetDescription(bpkt_loc_desc, lldb.eDescriptionLevelVerbose))
            self.assertIn("main.cpp:{}:{}".format(loc['line'], nearest_column[idx]),
                          bpkt_loc_desc.GetData())
            bpkt_loc_addr = bpkt_loc.GetAddress()
            self.assertTrue(bpkt_loc_addr)

            list = target.FindCompileUnits(lldb.SBFileSpec("main.cpp", False))
            # Executable has been built just from one source file 'main.cpp',
            # so we may check only the first element of list.
            compile_unit = list[0].GetCompileUnit()

            found = False
            for line_entry in compile_unit:
                if line_entry.GetStartAddress() == bpkt_loc_addr:
                    self.assertEqual(line_entry.GetFileSpec().GetFilename(),
                                    "main.cpp")
                    self.assertEqual(line_entry.GetLine(), loc['line'])
                    self.assertEqual(line_entry.GetColumn(), nearest_column[idx])
                    found = True
                    break

            self.assertTrue(found)

        line = line_number("main.cpp", "// This is a random comment.")
        column = len("// This is a random comment.")
        indent = 2
        invalid_bpkt = target.BreakpointCreateByLocation(src_file, line, column,
                                                      indent, module_list, False)
        self.assertTrue(invalid_bpkt, VALID_BREAKPOINT)
        self.assertEqual(invalid_bpkt.GetNumLocations(), 0)

