"""Test function call thread safety."""

from __future__ import print_function


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


class TestSafeFuncCalls(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line numbers that we will step to in main:
        self.main_source = "main.c"

    @skipUnlessDarwin
    @add_test_categories(['pyapi'])
    def test_with_python_api(self):
        """Test function call thread safety."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)
        self.main_source_spec = lldb.SBFileSpec(self.main_source)
        break1 = target.BreakpointCreateByName("stopper", 'a.out')
        self.assertTrue(break1, VALID_BREAKPOINT)
        process = target.LaunchSimple(
            None, None, self.get_process_working_directory())
        self.assertTrue(process, PROCESS_IS_VALID)
        threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1)
        if len(threads) != 1:
            self.fail("Failed to stop at breakpoint 1.")

        self.check_number_of_threads(process)

        main_thread = lldb.SBThread()
        select_thread = lldb.SBThread()
        for idx in range(0, process.GetNumThreads()):
            t = process.GetThreadAtIndex(idx)
            if t.GetName() == "main thread":
                main_thread = t
            if t.GetName() == "select thread":
                select_thread = t

        self.assertTrue(
            main_thread.IsValid() and select_thread.IsValid(),
            "Got both expected threads")

        self.safe_to_call_func_on_main_thread(main_thread)
        self.safe_to_call_func_on_select_thread(select_thread)

    def check_number_of_threads(self, process):
        self.assertTrue(
            process.GetNumThreads() == 2,
            "Check that the process has two threads when sitting at the stopper() breakpoint")

    def safe_to_call_func_on_main_thread(self, main_thread):
        self.assertTrue(main_thread.SafeToCallFunctions(),
                        "It is safe to call functions on the main thread")

    def safe_to_call_func_on_select_thread(self, select_thread):
        self.assertTrue(
            select_thread.SafeToCallFunctions() == False,
            "It is not safe to call functions on the select thread")
