# By: Riasat Ullah
# This file contains queries that handle user information in cache.

from utils import cache_names, helpers
import json


def store_single_user_policy_info(client, policy_id, info):
    '''
    Stores the policy info of a single user.
    :param client: cache client
    :param policy_id: policy ID of the user
    :param info: (dict) of user info
    '''
    client.hset(cache_names.user_policy_info, policy_id, json.dumps(info, default=helpers.jsonify_unserializable))


def store_multiple_user_policy_into(client, info):
    '''
    Stores the details of a user policy related to sending notifications.
    :param client: cache client
    :param info: (dict) of user info
    '''
    assert isinstance(info, dict) and len(info) > 0
    data = dict()
    for id_ in info:
        data[id_] = json.dumps(info[id_], default=helpers.jsonify_unserializable)
    client.hmset(cache_names.user_policy_info, data)


def get_multiple_users_policy_info(client, policy_ids):
    '''
    Get the info stored in cached for multiple users.
    :param client: cache client
    :param policy_ids: (list of int) of policy IDs
    :return: (dict) -> {policy ID: { dict }, ...}
    '''
    info_json = client.hmget(cache_names.user_policy_info, policy_ids)
    data = dict()
    if info_json is not None:
        for i in range(0, len(info_json)):
            if info_json[i] is not None:
                data[policy_ids[i]] = json.loads(info_json[i])
    return data


def get_all_users_policy_info(client):
    '''
    Get the info stored about all user policies from the cache.
    :param client: cache client
    :return: (dict) -> {policy ID: {user info}, ...}
    '''
    info_json = client.hgetall(cache_names.user_policy_info)
    data = dict()
    if info_json is not None:
        for id_ in info_json:
            data[id_] = json.loads(info_json[id_])
    return data


def remove_user_policy_info(client, policy_ids):
    '''
    Remove certain user policy info from cache.
    :param client: cache client
    :param policy_ids: (list of int) of policy IDs
    '''
    policy_ids = helpers.get_int_list(policy_ids)
    if len(policy_ids) > 0:
        client.hdel(cache_names.user_policy_info, *policy_ids)


def remove_all_user_policy_info(client):
    '''
    Removes all user info from cache.
    :param client: cache client
    '''
    client.delete(cache_names.user_policy_info)


def get_cached_user_policy_id_from_info(client):
    '''
    Get the policy IDs of all users whose info are cached in user info.
    :param client: cache client
    :return: (list) of user policy ID
    '''
    user_ids = client.hkeys(cache_names.user_policy_info)
    return [int(x) for x in user_ids] if user_ids is not None else []


def is_user_policy_in_cache(client, policy_id):
    '''
    Checks if a certain user policy is in cache or not.
    :param client: cache client
    :param policy_id: policy ID to check for
    :return: (boolean) True if it is in cache; False otherwise
    '''
    assert isinstance(policy_id, int)
    return client.hexists(cache_names.user_policy_info, policy_id)
