import lldb
import threading

local_data = None


class BarrierContainer(threading.local):
    def __init__(self, before_interrupt_barrier, after_interrupt_barrier, event):
        self.event = event
        self.before_interrupt_barrier = before_interrupt_barrier
        self.after_interrupt_barrier = after_interrupt_barrier


class WelcomeCommand(object):
    def __init__(self, debugger, session_dict):
        return

    def get_short_help(self):
        return "A command that waits for an interrupt before returning."

    def check_was_interrupted(self, debugger, use_interpreter):
        if use_interpreter:
            self.was_interrupted = debugger.GetCommandInterpreter().WasInterrupted()
        else:
            self.was_interrupted = debugger.InterruptRequested()
        if local_data.event:
            self.was_canceled = local_data.event.is_set()

    def __call__(self, debugger, args, exe_ctx, result):
        """Command arguments:
        {interp/debugger} - Whether to use SBCommandInterpreter::WasInterrupted
                            of SBDebugger::InterruptRequested().
        check - Don't do the rendevous, just check if an interrupt was requested.
                If check is not provided, we'll do the lock and then check.
        poll  - Should we poll once after the rendevous or spin waiting for the
                interruption to happen.

        For the interrupt cases, the command waits serially on the barriers
        passed to it in local data, giving the test runner a chance to set the
        interrupt.  Once the barriers are passed, it waits for the interrupt
        or the event.
        If it finds an interrupt, it returns "Command was interrupted". If it gets an
        event before seeing the interrupt it returns "Command was not interrupted."
        For the "poll" case, it waits on the rendevous, then checks once.
        For the "check" case, it doesn't wait, but just returns whether there was
        an interrupt in force or not."""

        if local_data is None:
            result.SetError("local data was not set.")
            result.SetStatus(lldb.eReturnStatusFailed)
            return

        use_interpreter = "interp" in args
        if not use_interpreter:
            if not "debugger" in args:
                result.SetError("Must pass either 'interp' or 'debugger'")
                result.SetStatus(lldb.eReturnStatusFailed)
                return

        self.was_interrupted = False
        self.was_canceled = False

        if "check" in args:
            self.check_was_interrupted(debugger, use_interpreter)
            if self.was_interrupted:
                result.Print("Command was interrupted")
            else:
                result.Print("Command was not interrupted")
        else:
            # Wait here to rendevous in the test before it sets the interrupt.
            local_data.before_interrupt_barrier.wait()
            # Now the test will set the interrupt, and we can continue:
            local_data.after_interrupt_barrier.wait()

            if "poll" in args:
                self.check_was_interrupted(debugger, use_interpreter)
            else:
                while not self.was_interrupted and not self.was_canceled:
                    self.check_was_interrupted(debugger, use_interpreter)

            if self.was_interrupted:
                result.Print("Command was interrupted")
            else:
                result.Print("Command was not interrupted")

            if self.was_canceled:
                result.Print("Command was canceled")
        result.SetStatus(lldb.eReturnStatusSuccessFinishResult)
        return True
