#!/usr/bin/env python

import lldb
import struct


class OperatingSystemPlugIn(object):
    """Class that provides a OS plugin that along with the particular code in main.cpp
    emulates the following scenario:
          a) We stop in an OS Plugin created thread - which should be thread index 1
          b) We step-out from that thread
          c) We hit a breakpoint in another thread, and DON'T produce the OS Plugin thread.
          d) We continue, and when we hit the step out breakpoint, we again produce the same
             OS Plugin thread.
          main.cpp sets values into the global variable g_value, which we use to tell the OS
          plugin whether to produce the OS plugin thread or not.
          Since we are always producing an OS plugin thread with a backing thread, we don't
          need to implement get_register_info or get_register_data.
    """

    def __init__(self, process):
        """Initialization needs a valid.SBProcess object.

        This plug-in will get created after a live process is valid and has stopped for the
        first time."""
        print("Plugin initialized.")
        self.process = None
        self.start_stop_id = 0
        self.g_value = lldb.SBValue()

        if isinstance(process, lldb.SBProcess) and process.IsValid():
            self.process = process
            self.g_value = process.GetTarget().FindFirstGlobalVariable("g_value")
            if not self.g_value.IsValid():
                print("Could not find g_value")

    def create_thread(self, tid, context):
        print("Called create thread with tid: ", tid)
        return None

    def get_thread_info(self):
        g_value = self.g_value.GetValueAsUnsigned()
        print("Called get_thread_info: g_value: %d" % (g_value))
        if g_value == 0 or g_value == 2:
            return [
                {
                    "tid": 0x111111111,
                    "name": "one",
                    "queue": "queue1",
                    "state": "stopped",
                    "stop_reason": "breakpoint",
                    "core": 1,
                }
            ]
        else:
            return []

    def get_register_info(self):
        print("called get_register_info")
        return None

    def get_register_data(self, tid):
        print("Get register data called for tid: %d" % (tid))
        return None
