"""
Use lldb Python SBTarget API to iterate on the watchpoint(s) for the target.
"""

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


class WatchpointIteratorTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    # hardware watchpoints are not reported with a hardware index # on armv7 on ios devices
    def affected_by_radar_34564183(self):
        return (
            self.getArchitecture() in ["armv7", "armv7k", "arm64_32"]
        ) and self.platformIsDarwin()

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Our simple source filename.
        self.source = "main.c"
        # Find the line number to break inside main().
        self.line = line_number(self.source, "// Set break point at this line.")

    def test_watch_iter(self):
        """Exercise SBTarget.watchpoint_iter() API to iterate on the available watchpoints."""
        self.build()
        exe = self.getBuildArtifact("a.out")

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

        # Create a breakpoint on main.c in order to set our watchpoint later.
        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
        self.assertTrue(
            breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT
        )

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

        # We should be stopped due to the breakpoint.  Get frame #0.
        process = target.GetProcess()
        self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
        frame0 = thread.GetFrameAtIndex(0)

        # Watch 'global' for read and write.
        value = frame0.FindValue("global", lldb.eValueTypeVariableGlobal)
        error = lldb.SBError()
        watchpoint = value.Watch(True, False, True, error)
        self.assertTrue(
            value and watchpoint, "Successfully found the variable and set a watchpoint"
        )
        self.DebugSBValue(value)

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        # There should be only 1 watchpoint location under the target.
        self.assertEqual(target.GetNumWatchpoints(), 1)
        self.assertTrue(watchpoint.IsEnabled())
        watch_id = watchpoint.GetID()
        self.assertNotEqual(watch_id, 0)

        # Continue.  Expect the program to stop due to the variable being
        # written to.
        process.Continue()

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        # Print the stack traces.
        lldbutil.print_stacktraces(process)

        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint)
        self.assertTrue(thread, "The thread stopped due to watchpoint")
        self.DebugSBValue(value)

        # SBWatchpoint.GetDescription() takes a description level arg.
        print(lldbutil.get_description(watchpoint, lldb.eDescriptionLevelFull))

        # Now disable the 'rw' watchpoint.  The program won't stop when it reads
        # 'global' next.
        watchpoint.SetEnabled(False)
        self.assertFalse(watchpoint.IsEnabled())

        # Continue.  The program does not stop again when the variable is being
        # read from because the watchpoint location has been disabled.
        process.Continue()

        # At this point, the inferior process should have exited.
        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)

        # Verify some vital statistics and exercise the iterator API.
        for watchpoint in target.watchpoint_iter():
            self.assertTrue(watchpoint)
            self.assertEqual(watchpoint.GetWatchSize(), 4)
            self.assertEqual(watchpoint.GetHitCount(), 1)
            print(watchpoint)
