import ompdModule


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
