"""
Test number of threads.
"""

from __future__ import print_function


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


class NumberOfThreadsTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)
    NO_DEBUG_INFO_TESTCASE = True

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line numbers for our break points.
        self.thread3_notify_all_line = line_number('main.cpp', '// Set thread3 break point on notify_all at this line.')
        self.thread3_before_lock_line = line_number('main.cpp', '// thread3-before-lock')

    def test_number_of_threads(self):
        """Test number of threads."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        # This should create a breakpoint with 1 location.
        lldbutil.run_break_set_by_file_and_line(
            self, "main.cpp", self.thread3_notify_all_line, num_expected_locations=1)

        # The breakpoint list should show 1 location.
        self.expect(
            "breakpoint list -f",
            "Breakpoint location shown correctly",
            substrs=[
                "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" %
                self.thread3_notify_all_line])

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

        # Stopped once.
        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                    substrs=["stop reason = breakpoint 1."])

        # Get the target process
        target = self.dbg.GetSelectedTarget()
        process = target.GetProcess()

        # Get the number of threads
        num_threads = process.GetNumThreads()

        # Using std::thread may involve extra threads, so we assert that there are
        # at least 4 rather than exactly 4.
        self.assertTrue(
            num_threads >= 13,
            'Number of expected threads and actual threads do not match.')

    @skipIfDarwin # rdar://33462362
    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr37658")
    def test_unique_stacks(self):
        """Test backtrace unique with multiple threads executing the same stack."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        # Set a break point on the thread3 notify all (should get hit on threads 4-13).
        lldbutil.run_break_set_by_file_and_line(
            self, "main.cpp", self.thread3_before_lock_line, num_expected_locations=1)

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

        # Stopped once.
        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                    substrs=["stop reason = breakpoint 1."])

        process = self.process()

        # Get the number of threads
        num_threads = process.GetNumThreads()

        # Using std::thread may involve extra threads, so we assert that there are
        # at least 10 thread3's rather than exactly 10.
        self.assertTrue(
            num_threads >= 10,
            'Number of expected threads and actual threads do not match.')

        # Attempt to walk each of the thread's executing the thread3 function to
        # the same breakpoint.
        def is_thread3(thread):
            for frame in thread:
                if "thread3" in frame.GetFunctionName(): return True
            return False

        expect_threads = ""
        for i in range(num_threads):
            thread = process.GetThreadAtIndex(i)
            self.assertTrue(thread.IsValid())
            if not is_thread3(thread):
                continue

            # If we aren't stopped out the thread breakpoint try to resume.
            if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
                self.runCmd("thread continue %d"%(i+1))
            self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint)

            expect_threads += " #%d"%(i+1)

        # Construct our expected back trace string
        expect_string = "10 thread(s)%s" % (expect_threads)

        # Now that we are stopped, we should have 10 threads waiting in the
        # thread3 function. All of these threads should show as one stack.
        self.expect("thread backtrace unique",
                    "Backtrace with unique stack shown correctly",
                    substrs=[expect_string,
                        "main.cpp:%d"%self.thread3_before_lock_line])
