# (c) cavaliba.com - data - search.py

import re
from django.db.models import Q

from .models import DataInstance, DataEAV
#from .data import Instance



def get_query_from_request(request=None, classname=None, update_session=False):

    if not request:
        return None
    
    if not classname:
        return None
    
    
    query = None

    # GET request => URL param (priority) or session or blank
    if request.method == "GET":
        get_query = request.GET.get('query', None)
        if get_query is not None:
            if update_session:
                if "query" not in request.session:
                    request.session["query"] = {classname: get_query}
                else:
                    request.session["query"][classname] = get_query
                    request.session.modified = True
            return get_query
        try:
            return request.session["query"][classname]
        except:
            return None
    
    # POST request : store in session if valid
    elif request.method == "POST":
        query = request.POST.get('query', None)
        m = re.compile(r'^[a-zA-Z0-9()_\/\.\s:]*$')
        if not m.match(query):
            query = ""

        if update_session:
            if "query" not in request.session:
                request.session["query"] = {classname: query}
                #request.session.modified = True
            else:
                request.session["query"][classname] = query
                request.session.modified = True

    return query



def get_instance_from_query(query=None, classname=None, offset=None, limit=None, page=None, size=None):

    if not query:
        query = ""

    # special: related:REF_CLASSNAME:REF_KEYNAME
    if query.startswith('related:'):
        parts = query.split(':', 2)
        if len(parts) == 3:
            iids = get_instance_ids_from_related(parts[1], parts[2], classname)
            return DataInstance.objects.filter(id__in=iids)

    if page and size:
        offset = (page - 1) * size
        limit = offset + size
    if not offset:
        offset = 0
    if limit:
        try:
            int(limit)
            if limit <= 0:
                return
        except:
            return

    if len(query) > 0:
        q = Q()
        for item in query.split():
            q |= Q(keyname__icontains=item)
            q |= Q(displayname__icontains=item)
            q |= Q(data_json__icontains=item)

        if classname:
            qc = Q(classname=classname)
            q2 = qc & q
        else:
            q2 = q


        if limit:
            instances = DataInstance.objects.filter(q2)[offset:limit]
        else:
            instances = DataInstance.objects.filter(q2)[offset:]


    else:
        if limit:
            instances = DataInstance.objects.filter(classname=classname)[offset:limit]
        else:
            instances = DataInstance.objects.filter(classname=classname)[offset:]

    

    return instances


def get_instance_ids_from_related(ref_classname, ref_keyname, classname):
    return DataEAV.objects.filter(
        classname=classname,
        format='schema:' + ref_classname,
        value=ref_keyname,
    ).values_list('iid', flat=True).distinct()



