# By: Riasat Ullah

# This class represents a group level.

from objects.routine import Routine
from utils import var_names


class PolicyLevel(object):

    def __init__(self, level, minutes, routines):
        '''
        This represents a level of a policy.
        :param level: The level number.
        :param minutes: The number of minutes to stay in this level.
        :param routines: (list) of Routine objects
        '''
        self.level = level
        self.minutes = minutes
        self.routines = routines

    @staticmethod
    def create_level(details, for_display=False):
        '''
        Creates new PolicyLevel object from policy level info dict.
        :param details: (dict) of policy level info
        :param for_display: (boolean) True if the Policy(s)/Routine(s) should be mapped on to their reference IDs
        :return: PolicyLevel object
        '''
        routines = []
        for item in details[var_names.routines]:
            routines.append(Routine.create_routine(item, for_display))

        return PolicyLevel(details[var_names.assignee_level], details[var_names.level_minutes], routines)

    def get_on_call(self, check_datetime=None):
        '''
        Gets the users who are assigned for on-call duty at this level.
        :param check_datetime: (timestamp) the timestamp to check on
        :return: (list of tuples) -> [(user_id, display name, assignee policy id), ...] of the users who are on call
        '''
        on_call = []
        for routine in self.routines:
            on_call += routine.get_on_call(check_datetime)
        return on_call

    def get_all_assignees(self, skip_exceptions=True):
        '''
        Get the user_id of all the users who are in the rotation cycle of this level
        :param skip_exceptions: (boolean) True if exceptions should be ignored; False otherwise
        :return: (list of tuples) -> [(user_id, display_name), ...] of users
        '''
        assignees = []
        for routine in self.routines:
            assignees += routine.get_all_assignees(skip_exceptions)
        return assignees

    def to_dict(self, basic_info=False):
        '''
        Gets the dict of the PolicyLevel object.
        :param basic_info: specifies if only the routine id and name are required
        :return: dict of PolicyLevel object.
        '''
        routines_list = []
        for item in self.routines:
            # DO NOT pass basic_info = True directly on to the Routine object from PolicyLevel because the basic info
            # returned by routines is different from what is required by policies.
            if basic_info:
                routines_list.append([item.routine_name, item.routine_id])
            else:
                routines_list.append(item.to_dict())

        data = {var_names.assignee_level: self.level,
                var_names.level_minutes: self.minutes,
                var_names.routines: routines_list}

        return data
