"""
Set breakpoints on objective-c class and instance methods in foundation.
Also lookup objective-c data types and evaluate expressions.
"""

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

file_index = 0


class FoundationTestCase(TestBase):
    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line number to break inside main().
        self.main_source = "main.m"
        self.line = line_number(self.main_source, "// Set break point at this line.")

    def test_break(self):
        """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        # Stop at +[NSString stringWithFormat:].
        break_results = lldbutil.run_break_set_command(
            self, "_regexp-break +[NSString stringWithFormat:]"
        )
        lldbutil.check_breakpoint_result(
            self,
            break_results,
            symbol_name="+[NSString stringWithFormat:]",
            num_locations=1,
        )

        # Stop at -[MyString initWithNSString:].
        lldbutil.run_break_set_by_symbol(
            self,
            "-[MyString initWithNSString:]",
            num_expected_locations=1,
            sym_exact=True,
        )

        # Stop at the "description" selector.
        lldbutil.run_break_set_by_selector(
            self, "description", num_expected_locations=1, module_name="a.out"
        )

        # Stop at -[NSAutoreleasePool release].
        break_results = lldbutil.run_break_set_command(
            self, "_regexp-break -[NSAutoreleasePool release]"
        )
        lldbutil.check_breakpoint_result(
            self,
            break_results,
            symbol_name="-[NSAutoreleasePool release]",
            num_locations=1,
        )

        self.runCmd("run", RUN_SUCCEEDED)

        # First stop is +[NSString stringWithFormat:].
        self.expect(
            "thread backtrace",
            "Stop at +[NSString stringWithFormat:]",
            substrs=["Foundation`+[NSString stringWithFormat:]"],
        )

        self.runCmd("process continue")

        # Second stop is still +[NSString stringWithFormat:].
        self.expect(
            "thread backtrace",
            "Stop at +[NSString stringWithFormat:]",
            substrs=["Foundation`+[NSString stringWithFormat:]"],
        )

        self.runCmd("process continue")

        # Followed by a.out`-[MyString initWithNSString:].
        self.expect(
            "thread backtrace",
            "Stop at a.out`-[MyString initWithNSString:]",
            substrs=["a.out`-[MyString initWithNSString:]"],
        )

        self.runCmd("process continue")

        # Followed by -[MyString description].
        self.expect(
            "thread backtrace",
            "Stop at -[MyString description]",
            substrs=["a.out`-[MyString description]"],
        )

        self.runCmd("process continue")

        # Followed by the same -[MyString description].
        self.expect(
            "thread backtrace",
            "Stop at -[MyString description]",
            substrs=["a.out`-[MyString description]"],
        )

        self.runCmd("process continue")

        # Followed by -[NSAutoreleasePool release].
        self.expect(
            "thread backtrace",
            "Stop at -[NSAutoreleasePool release]",
            substrs=["Foundation`-[NSAutoreleasePool release]"],
        )

    # rdar://problem/8542091
    # rdar://problem/8492646
    def test_data_type_and_expr(self):
        """Lookup objective-c data types and evaluate expressions."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        # Stop at -[MyString description].
        lldbutil.run_break_set_by_symbol(
            self, "-[MyString description]", num_expected_locations=1, sym_exact=True
        )
        #        self.expect("breakpoint set -n '-[MyString description]", BREAKPOINT_CREATED,
        # startstr = "Breakpoint created: 1: name = '-[MyString description]',
        # locations = 1")

        self.runCmd("run", RUN_SUCCEEDED)

        self.runCmd("settings set target.prefer-dynamic-value no-dynamic-values")

        # The backtrace should show we stop at -[MyString description].
        self.expect(
            "thread backtrace",
            "Stop at -[MyString description]",
            substrs=["a.out`-[MyString description]"],
        )

        # Lookup objc data type MyString and evaluate some expressions.

        self.expect(
            "image lookup -t NSString",
            DATA_TYPES_DISPLAYED_CORRECTLY,
            substrs=['name = "NSString"', 'compiler_type = "@interface NSString'],
        )

        self.expect(
            "image lookup -t MyString",
            DATA_TYPES_DISPLAYED_CORRECTLY,
            substrs=[
                'name = "MyString"',
                'compiler_type = "@interface MyString',
                "NSString * str;",
                "NSDate * date;",
            ],
        )

        self.expect(
            "frame variable --show-types --scope",
            VARIABLES_DISPLAYED_CORRECTLY,
            substrs=["ARG: (MyString *) self"],
            patterns=["ARG: \(.*\) _cmd", "(objc_selector *)|(SEL)"],
        )

        # rdar://problem/8651752
        # don't crash trying to ask clang how many children an empty record has
        self.runCmd("frame variable *_cmd")

        # rdar://problem/8492646
        # test/foundation fails after updating to tot r115023
        # self->str displays nothing as output
        self.expect(
            "frame variable --show-types self->str",
            VARIABLES_DISPLAYED_CORRECTLY,
            startstr="(NSString *) self->str",
        )

        # rdar://problem/8447030
        # 'frame variable self->date' displays the wrong data member
        self.expect(
            "frame variable --show-types self->date",
            VARIABLES_DISPLAYED_CORRECTLY,
            startstr="(NSDate *) self->date",
        )

        # This should display the str and date member fields as well.
        self.expect(
            "frame variable --show-types *self",
            VARIABLES_DISPLAYED_CORRECTLY,
            substrs=["(MyString) *self", "(NSString *) str", "(NSDate *) date"],
        )

        # isa should be accessible.
        self.expect(
            "expression self->isa", VARIABLES_DISPLAYED_CORRECTLY, substrs=["Class)"]
        )

        # This should fail expectedly.
        self.expect(
            "expression self->non_existent_member",
            COMMAND_FAILED_AS_EXPECTED,
            error=True,
            substrs=[
                "error:",
                "'MyString' does not have a member named 'non_existent_member'",
            ],
        )

        # Use expression parser.
        self.runCmd("expression self->str")
        self.runCmd("expression self->date")

        # (lldb) expression self->str
        # error: instance variable 'str' is protected
        # error: 1 errors parsing expression
        #
        # (lldb) expression self->date
        # error: instance variable 'date' is protected
        # error: 1 errors parsing expression
        #

        self.runCmd("breakpoint delete 1")
        lldbutil.run_break_set_by_file_and_line(
            self, "main.m", self.line, num_expected_locations=1, loc_exact=True
        )

        self.runCmd("process continue")

        # rdar://problem/8542091
        # test/foundation: expr -o -- my not working?
        #
        # Test new feature with r115115:
        # Add "-o" option to "expression" which prints the object description
        # if available.
        self.expect(
            "expression --object-description -- my",
            "Object description displayed correctly",
            patterns=["Hello from.*a.out.*with timestamp: "],
        )

    @add_test_categories(["pyapi"])
    def test_print_ivars_correctly(self):
        self.build()
        # See: <rdar://problem/8717050> lldb needs to use the ObjC runtime symbols for ivar offsets
        # Only fails for the ObjC 2.0 runtime.
        exe = self.getBuildArtifact("a.out")

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

        break1 = target.BreakpointCreateByLocation(self.main_source, self.line)
        self.assertTrue(break1, VALID_BREAKPOINT)

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())

        self.assertTrue(process, PROCESS_IS_VALID)

        # The stop reason of the thread should be breakpoint.
        thread = process.GetThreadAtIndex(0)
        if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
            from lldbsuite.test.lldbutil import stop_reason_to_str

            self.fail(
                STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS
                % stop_reason_to_str(thread.GetStopReason())
            )

        # Make sure we stopped at the first breakpoint.

        cur_frame = thread.GetFrameAtIndex(0)

        line_number = cur_frame.GetLineEntry().GetLine()
        self.assertEqual(line_number, self.line, "Hit the first breakpoint.")

        my_var = cur_frame.FindVariable("my")
        self.assertTrue(my_var, "Made a variable object for my")

        str_var = cur_frame.FindVariable("str")
        self.assertTrue(str_var, "Made a variable object for str")

        # Now make sure that the my->str == str:

        my_str_var = my_var.GetChildMemberWithName("str")
        self.assertTrue(my_str_var, "Found a str ivar in my")

        str_value = int(str_var.GetValue(), 0)

        my_str_value = int(my_str_var.GetValue(), 0)

        self.assertEqual(str_value, my_str_value, "Got the correct value for my->str")

    def test_expression_lookups_objc(self):
        """Test running an expression detect spurious debug info lookups (DWARF)."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        # Stop at -[MyString initWithNSString:].
        lldbutil.run_break_set_by_symbol(
            self,
            "-[MyString initWithNSString:]",
            num_expected_locations=1,
            sym_exact=True,
        )

        self.runCmd("run", RUN_SUCCEEDED)

        global file_index
        # Log any DWARF lookups
        ++file_index
        logfile = os.path.join(
            self.getBuildDir(),
            "dwarf-lookups-" + self.getArchitecture() + "-" + str(file_index) + ".txt",
        )
        self.runCmd("log enable -f %s dwarf lookups" % (logfile))
        self.runCmd("expr self")
        self.runCmd("log disable dwarf lookups")

        def cleanup():
            if os.path.exists(logfile):
                os.unlink(logfile)

        self.addTearDownHook(cleanup)

        if os.path.exists(logfile):
            f = open(logfile)
            lines = f.readlines()
            num_errors = 0
            for line in lines:
                if "$__lldb" in line:
                    if num_errors == 0:
                        print(
                            "error: found spurious name lookups when evaluating an expression:"
                        )
                    num_errors += 1
                    print(line, end="")
            self.assertEqual(num_errors, 0, "Spurious lookups detected")
            f.close()
