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

from __future__ import print_function


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

file_index = 0


@skipUnlessDarwin
class FoundationTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    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)

        # 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,
            startstr="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.assertTrue(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.assertTrue(
            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.assertTrue(num_errors == 0, "Spurious lookups detected")
            f.close()
