"""
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 os
import time
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))
