import ompdModule
import imp


class ompd_parallel(object):
    def __init__(self, parallel_handle):
        """Initializes an ompd_parallel object with the pointer
        to a handle of a parallel region."""
        self.parallel_handle = parallel_handle
        self.threads = {}
        self.itasks = {}
        self.enclosing_parallel_handle = None
        self.enclosing_parallel = False
        self.task_handle = None

    def get_thread_in_parallel(self, thread_num):
        """Obtains thread handles for the threads associated with the
        parallel region specified by parallel_handle."""
        if not thread_num in self.threads:
            thread_handle = ompdModule.call_ompd_get_thread_in_parallel(
                self.parallel_handle, thread_num
            )
            self.threads[thread_num] = ompd_thread(thread_handle)
        return self.threads[thread_num]

    def get_enclosing_parallel_handle(self):
        """Obtains a parallel handle for the parallel region enclosing
        the parallel region specified by parallel_handle."""
        if not self.enclosing_parallel_handle:
            self.enclosing_parallel_handle = (
                ompdModule.call_ompd_get_enclosing_parallel_handle(self.parallel_handle)
            )
        return self.enclosing_parallel_handle

    def get_enclosing_parallel(self):
        if not self.enclosing_parallel:
            self.enclosing_parallel = ompd_parallel(
                self.get_enclosing_parallel_handle()
            )
        return self.enclosing_parallel

    def get_task_in_parallel(self, thread_num):
        """Obtains handles for the implicit tasks associated with the
        parallel region specified by parallel_handle."""
        if not thread_num in self.itasks:
            task_handle = ompdModule.call_ompd_get_task_in_parallel(
                self.parallel_handle, thread_num
            )
            self.itasks[thread_num] = ompd_task(task_handle)
        return self.itasks[thread_num]

    def __del__(self):
        """Releases the parallel handle."""
        pass  # let capsule destructors do the job


class ompd_task(object):
    def __init__(self, task_handle):
        """Initializes a new ompd_task_handle object and sets the attribute
        to the task handle specified."""
        self.task_handle = task_handle
        self.task_parallel_handle = False
        self.generating_task_handle = False
        self.scheduling_task_handle = False
        self.task_parallel = False
        self.generating_task = False
        self.scheduling_task = False
        self.task_frames = None
        self.task_frame_flags = None

    def get_task_parallel_handle(self):
        """Obtains a task parallel handle for the parallel region enclosing
        the task region specified."""
        if not self.task_parallel_handle:
            self.task_parallel_handle = ompdModule.call_ompd_get_task_parallel_handle(
                self.task_handle
            )
        return self.task_parallel_handle

    def get_task_parallel(self):
        if not self.task_parallel:
            self.task_parallel = ompd_parallel(self.get_task_parallel_handle())
        return self.task_parallel

    def get_generating_task_handle(self):
        """Obtains the task handle for the task that created the task specified
        by the task handle."""
        if not self.generating_task_handle:
            self.generating_task_handle = (
                ompdModule.call_ompd_get_generating_task_handle(self.task_handle)
            )
        return self.generating_task_handle

    def get_generating_task(self):
        if not self.generating_task:
            self.generating_task = ompd_task(
                ompdModule.call_ompd_get_generating_task_handle(self.task_handle)
            )
        return self.generating_task

    def get_scheduling_task_handle(self):
        """Obtains the task handle for the task that scheduled the task specified."""
        if not self.scheduling_task_handle:
            self.scheduling_task_handle = (
                ompdModule.call_ompd_get_scheduling_task_handle(self.task_handle)
            )
        return self.scheduling_task_handle

    def get_scheduling_task(self):
        """Returns ompd_task object for the task that scheduled the current task."""
        if not self.scheduling_task:
            self.scheduling_task = ompd_task(self.get_scheduling_task_handle())
        return self.scheduling_task

    def get_task_function(self):
        """Returns long with address of function entry point."""
        return ompdModule.call_ompd_get_task_function(self.task_handle)

    def get_task_frame_with_flags(self):
        """Returns enter frame address and flag, exit frame address and flag for current task handle."""
        if self.task_frames is None or self.task_frame_flags is None:
            ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle)
            if isinstance(ret_value, tuple):
                self.task_frames = (ret_value[0], ret_value[2])
                self.task_frame_flags = (ret_value[1], ret_value[3])
            else:
                return ret_value
        return (
            self.task_frames[0],
            self.task_frame_flags[0],
            self.task_frames[1],
            self.task_frame_flags[1],
        )

    def get_task_frame(self):
        """Returns enter and exit frame address for current task handle."""
        if self.task_frames is None:
            ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle)
            if isinstance(ret_value, tuple):
                self.task_frames = (ret_value[0], ret_value[2])
            else:
                return ret_value
        return self.task_frames

    def __del__(self):
        """Releases the task handle."""
        pass  # let capsule destructors do the job


class ompd_thread(object):
    def __init__(self, thread_handle):
        """Initializes an ompd_thread with the data received from
        GDB."""
        self.thread_handle = thread_handle
        self.parallel_handle = None
        self.task_handle = None
        self.current_task = False
        self.current_parallel = False
        self.thread_id = False

    def get_current_parallel_handle(self):
        """Obtains the parallel handle for the parallel region associated with
        the given thread handle."""
        # TODO: invalidate thread objects based on `gdb.event.cont`. This should invalidate all internal state.
        self.parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(
            self.thread_handle
        )
        return self.parallel_handle

    def get_current_parallel(self):
        """Returns parallel object for parallel handle of the parallel region
        associated with the current thread handle."""
        if not self.current_parallel:
            self.current_parallel = ompd_parallel(self.get_current_parallel_handle())
        return self.current_parallel

    def get_current_task_handle(self):
        """Obtains the task handle for the current task region of the
        given thread."""
        return ompdModule.call_ompd_get_curr_task_handle(self.thread_handle)

    def get_thread_id(self):
        """Obtains the ID for the given thread."""
        if not self.thread_id:
            self.thread_id = ompdModule.call_ompd_get_thread_id(self.thread_handle)
        return self.thread_id

    def get_current_task(self):
        """Returns task object for task handle of the current task region."""
        return ompd_task(self.get_current_task_handle())

    def get_state(self):
        """Returns tuple with OMPD state (long) and wait_id, in case the thread is in a
        waiting state. Helper function for 'ompd threads' command."""
        (state, wait_id) = ompdModule.call_ompd_get_state(self.thread_handle)
        return (state, wait_id)

    def __del__(self):
        """Releases the given thread handle."""
        pass  # let capsule destructors do the job
