import bencode
import hashlib
import json
import uuid
from datetime import datetime
from itertools import chain

from django.core.cache import cache
from django.conf import settings
from django.core.paginator import Paginator
from django.core.urlresolvers import reverse
from django.db.models import Q

from . import convert_to_datetime_object
from ..models import Statement, Agent
from ..exceptions import NotFound


def complex_get(param_dict, limit, language, stmt_format, attachments):
    # keep track if a filter other than time or sequence is used
    reffilter = False

    sinceQ = Q()
    if 'since' in param_dict:
        sinceQ = Q(stored__gt=convert_to_datetime_object(param_dict['since']))

    untilQ = Q()
    if 'until' in param_dict:
        untilQ = Q(stored__lte=convert_to_datetime_object(param_dict['until']))

    # If want ordered by ascending
    stored_param = '-stored'
    if 'ascending' in param_dict and param_dict['ascending']:
        stored_param = 'stored'

    # For statements/read/mine oauth scope
    authQ = Q()
    if 'auth' in param_dict and (param_dict['auth'] and 'statements_mine_only' in param_dict['auth']):
        q_auth = param_dict['auth']['agent']

        # If oauth - set authority to look for as the user
        if q_auth.oauth_identifier:
            authQ = Q(authority=q_auth) | Q(
                authority=q_auth.get_user_from_oauth_group())
        # Chain all of user's oauth clients as well
        else:
            oauth_clients = Agent.objects.filter(member__in=[q_auth])
            authQ = Q(authority=q_auth)
            for client in oauth_clients:
                authQ = authQ | Q(authority=client.get_user_from_oauth_group())

    agentQ = Q()
    if 'agent' in param_dict:
        reffilter = True
        agent = None
        data = param_dict['agent']
        related = 'related_agents' in param_dict and param_dict[
            'related_agents']
        agent = Agent.objects.retrieve(**data)
        if agent:
            agentQ = Q(actor=agent) | Q(object_agent=agent)
            if related:
                agentQ = agentQ | Q(authority=agent) \
                    | Q(context_instructor=agent) | Q(context_team=agent) \
                    | Q(object_substatement__actor=agent) \
                    | Q(object_substatement__object_agent=agent) \