"""
A stress-test of sorts for LLDB's handling of threads in the inferior.

This test sets a breakpoint in the main thread where test parameters (numbers of
threads) can be adjusted, runs the inferior to that point, and modifies the
locals that control the event thread counts. This test also sets a breakpoint in
breakpoint_func (the function executed by each 'breakpoint' thread) and a
watchpoint on a global modified in watchpoint_func. The inferior is continued
until exit or a crash takes place, and the number of events seen by LLDB is
verified to match the expected number of events.
"""

from __future__ import print_function


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


class ConcurrentEventsBase(TestBase):

    # Concurrency is the primary test factor here, not debug info variants.
    NO_DEBUG_INFO_TESTCASE = True

    def setUp(self):
        # Call super's setUp().
        super(ConcurrentEventsBase, self).setUp()
        # Find the line number for our breakpoint.
        self.filename = 'main.cpp'
        self.thread_breakpoint_line = line_number(
            self.filename, '// Set breakpoint here')
        self.setup_breakpoint_line = line_number(
            self.filename, '// Break here and adjust num')
        self.finish_breakpoint_line = line_number(
            self.filename, '// Break here and verify one thread is active')

    def describe_threads(self):
        ret = []
        for x in self.inferior_process:
            id = x.GetIndexID()
            reason = x.GetStopReason()
            status = "stopped" if x.IsStopped() else "running"
            reason_str = lldbutil.stop_reason_to_str(reason)
            if reason == lldb.eStopReasonBreakpoint:
                bpid = x.GetStopReasonDataAtIndex(0)
                bp = self.inferior_target.FindBreakpointByID(bpid)
                reason_str = "%s hit %d times" % (
                    lldbutil.get_description(bp), bp.GetHitCount())
            elif reason == lldb.eStopReasonWatchpoint:
                watchid = x.GetStopReasonDataAtIndex(0)
                watch = self.inferior_target.FindWatchpointByID(watchid)
                reason_str = "%s hit %d times" % (
                    lldbutil.get_description(watch), watch.GetHitCount())
            elif reason == lldb.eStopReasonSignal:
                signals = self.inferior_process.GetUnixSignals()
                signal_name = signals.GetSignalAsCString(
                    x.GetStopReasonDataAtIndex(0))
                reason_str = "signal %s" % signal_name

            location = "\t".join([lldbutil.get_description(
                x.GetFrameAtIndex(i)) for i in range(x.GetNumFrames())])
            ret.append(
                "thread %d %s due to %s at\n\t%s" %
                (id, status, reason_str, location))
        return ret

    def add_breakpoint(self, line, descriptions):
        """ Adds a breakpoint at self.filename:line and appends its description to descriptions, and
            returns the LLDB SBBreakpoint object.
        """

        bpno = lldbutil.run_break_set_by_file_and_line(
            self, self.filename, line, num_expected_locations=-1)
        bp = self.inferior_target.FindBreakpointByID(bpno)
        descriptions.append(
            ": file = 'main.cpp', line = %d" %
            self.finish_breakpoint_line)
        return bp

    def inferior_done(self):
        """ Returns true if the inferior is done executing all the event threads (and is stopped at self.finish_breakpoint,
            or has terminated execution.
        """
        return self.finish_breakpoint.GetHitCount() > 0 or \
            self.crash_count > 0 or \
            self.inferior_process.GetState() == lldb.eStateExited

    def count_signaled_threads(self):
        count = 0
        for thread in self.inferior_process:
            if thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(
                    0) == self.inferior_process.GetUnixSignals().GetSignalNumberFromName('SIGUSR1'):
                count += 1
        return count

    def do_thread_actions(self,
                          num_breakpoint_threads=0,
                          num_signal_threads=0,
                          num_watchpoint_threads=0,
                          num_crash_threads=0,
                          num_delay_breakpoint_threads=0,
                          num_delay_signal_threads=0,
                          num_delay_watchpoint_threads=0,
                          num_delay_crash_threads=0):
        """ Sets a breakpoint in the main thread where test parameters (numbers of threads) can be adjusted, runs the inferior
            to that point, and modifies the locals that control the event thread counts. Also sets a breakpoint in
            breakpoint_func (the function executed by each 'breakpoint' thread) and a watchpoint on a global modified in
            watchpoint_func. The inferior is continued until exit or a crash takes place, and the number of events seen by LLDB
            is verified to match the expected number of events.
        """
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        # Get the target
        self.inferior_target = self.dbg.GetSelectedTarget()

        expected_bps = []

        # Initialize all the breakpoints (main thread/aux thread)
        self.setup_breakpoint = self.add_breakpoint(
            self.setup_breakpoint_line, expected_bps)
        self.finish_breakpoint = self.add_breakpoint(
            self.finish_breakpoint_line, expected_bps)

        # Set the thread breakpoint
        if num_breakpoint_threads + num_delay_breakpoint_threads > 0:
            self.thread_breakpoint = self.add_breakpoint(
                self.thread_breakpoint_line, expected_bps)

        # Verify breakpoints
        self.expect(
            "breakpoint list -f",
            "Breakpoint locations shown correctly",
            substrs=expected_bps)

        # Run the program.
        self.runCmd("run", RUN_SUCCEEDED)

        # Check we are at line self.setup_breakpoint
        self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
                    substrs=["stop reason = breakpoint 1."])

        # Initialize the (single) watchpoint on the global variable (g_watchme)
        if num_watchpoint_threads + num_delay_watchpoint_threads > 0:
            self.runCmd("watchpoint set variable g_watchme")
            for w in self.inferior_target.watchpoint_iter():
                self.thread_watchpoint = w
                self.assertTrue(
                    "g_watchme" in str(
                        self.thread_watchpoint),
                    "Watchpoint location not shown correctly")

        # Get the process
        self.inferior_process = self.inferior_target.GetProcess()

        # We should be stopped at the setup site where we can set the number of
        # threads doing each action (break/crash/signal/watch)
        self.assertEqual(
            self.inferior_process.GetNumThreads(),
            1,
            'Expected to stop before any additional threads are spawned.')

        self.runCmd("expr num_breakpoint_threads=%d" % num_breakpoint_threads)
        self.runCmd("expr num_crash_threads=%d" % num_crash_threads)
        self.runCmd("expr num_signal_threads=%d" % num_signal_threads)
        self.runCmd("expr num_watchpoint_threads=%d" % num_watchpoint_threads)

        self.runCmd(
            "expr num_delay_breakpoint_threads=%d" %
            num_delay_breakpoint_threads)
        self.runCmd(
            "expr num_delay_crash_threads=%d" %
            num_delay_crash_threads)
        self.runCmd(
            "expr num_delay_signal_threads=%d" %
            num_delay_signal_threads)
        self.runCmd(
            "expr num_delay_watchpoint_threads=%d" %
            num_delay_watchpoint_threads)

        # Continue the inferior so threads are spawned
        self.runCmd("continue")

        # Make sure we see all the threads. The inferior program's threads all synchronize with a pseudo-barrier; that is,
        # the inferior program ensures all threads are started and running
        # before any thread triggers its 'event'.
        num_threads = self.inferior_process.GetNumThreads()
        expected_num_threads = num_breakpoint_threads + num_delay_breakpoint_threads \
            + num_signal_threads + num_delay_signal_threads \
            + num_watchpoint_threads + num_delay_watchpoint_threads \
            + num_crash_threads + num_delay_crash_threads + 1
        self.assertEqual(
            num_threads,
            expected_num_threads,
            'Expected to see %d threads, but seeing %d. Details:\n%s' %
            (expected_num_threads,
             num_threads,
             "\n\t".join(
                 self.describe_threads())))

        self.signal_count = self.count_signaled_threads()
        self.crash_count = len(
            lldbutil.get_crashed_threads(
                self, self.inferior_process))

        # Run to completion (or crash)
        while not self.inferior_done():
            if self.TraceOn():
                self.runCmd("thread backtrace all")
            self.runCmd("continue")
            self.signal_count += self.count_signaled_threads()
            self.crash_count += len(
                lldbutil.get_crashed_threads(
                    self, self.inferior_process))

        if num_crash_threads > 0 or num_delay_crash_threads > 0:
            # Expecting a crash
            self.assertTrue(
                self.crash_count > 0,
                "Expecting at least one thread to crash. Details: %s" %
                "\t\n".join(
                    self.describe_threads()))

            # Ensure the zombie process is reaped
            self.runCmd("process kill")

        elif num_crash_threads == 0 and num_delay_crash_threads == 0:
            # There should be a single active thread (the main one) which hit
            # the breakpoint after joining
            self.assertEqual(
                1,
                self.finish_breakpoint.GetHitCount(),
                "Expected main thread (finish) breakpoint to be hit once")

            num_threads = self.inferior_process.GetNumThreads()
            self.assertEqual(
                1,
                num_threads,
                "Expecting 1 thread but seeing %d. Details:%s" %
                (num_threads,
                 "\n\t".join(
                     self.describe_threads())))
            self.runCmd("continue")

            # The inferior process should have exited without crashing
            self.assertEqual(
                0,
                self.crash_count,
                "Unexpected thread(s) in crashed state")
            self.assertEqual(
                self.inferior_process.GetState(),
                lldb.eStateExited,
                PROCESS_EXITED)

            # Verify the number of actions took place matches expected numbers
            expected_breakpoint_threads = num_delay_breakpoint_threads + num_breakpoint_threads
            breakpoint_hit_count = self.thread_breakpoint.GetHitCount(
            ) if expected_breakpoint_threads > 0 else 0
            self.assertEqual(
                expected_breakpoint_threads,
                breakpoint_hit_count,
                "Expected %d breakpoint hits, but got %d" %
                (expected_breakpoint_threads,
                 breakpoint_hit_count))

            expected_signal_threads = num_delay_signal_threads + num_signal_threads
            self.assertEqual(
                expected_signal_threads,
                self.signal_count,
                "Expected %d stops due to signal delivery, but got %d" %
                (expected_signal_threads,
                 self.signal_count))

            expected_watchpoint_threads = num_delay_watchpoint_threads + num_watchpoint_threads
            watchpoint_hit_count = self.thread_watchpoint.GetHitCount(
            ) if expected_watchpoint_threads > 0 else 0
            self.assertEqual(
                expected_watchpoint_threads,
                watchpoint_hit_count,
                "Expected %d watchpoint hits, got %d" %
                (expected_watchpoint_threads,
                 watchpoint_hit_count))
