
from pymongo import MongoClient
import pymongo
import json
from flask import Flask, request, jsonify
#from flask_mongoengine import MongoEngine
import json
from bson import ObjectId
import re
import numpy as np
import ela_index_bdd_classes as ela_index
import logging
from datetime import datetime
import prj_common as mycommon
import secrets
from pymongo import ReturnDocument
import inspect
import os
import csv
import pandas as pd



class JSONEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, ObjectId):
            return str(o)
        return json.JSONEncoder.default(self, o)

CONNECTION_STRING = "mongodb://localhost/cherifdb"
client = MongoClient(CONNECTION_STRING)
dbname = client['cherifdb']



def get_recherche_gle_class(sentence):
    try:
        if not sentence:
            return False

        mycommon.myprint(" On recehrche la phrase +'"+sentence+"'")

        tab_training = []
        tab_training = ela_index.ela_recherche_tokens(sentence)
        mycommon.myprint(" pour phrase : #"+sentence+"#, voici la liste des formations")
        mycommon.myprint(tab_training)


        coll_name = dbname['myclass']

        insertObject = []
        for x in coll_name.find({"external_code": {"$in": tab_training}}, {"_id": 0}):
            mycommon.myprint(x)
            user = x
            insertObject.append(JSONEncoder().encode(user))

        # mycommon.myprint(" insertObject = ", insertObject)
        return insertObject

    except Exception as e:
        mycommon.myprint(e)
        return False



def get_class_by_list_attr(attribut, list_values):
    try:
        ela_array = []
        ela_array = list_values.split(",")
        mycommon.myprint(" attribut"+ attribut+"  ==> list_values = "+ela_array)
        client = MongoClient(CONNECTION_STRING)

        dbname = client['cherifdb']
        coll_name = dbname['myclass']

        insertObject = []
        for x in coll_name.find({attribut:{ "$in":ela_array}},{"_id": 0}):
            mycommon.myprint(x)
            user = x
            insertObject.append(JSONEncoder().encode(user))

        #mycommon.myprint(" insertObject = ", insertObject)
        return insertObject

    except Exception as e:
        mycommon.myprint(e)
        return False



def update_class_by_attribut(objId, attribut, value):
    try:
        mycommon.myprint("objId = "+objId+" attribut "+attribut+" value = "+value)
        client = MongoClient(CONNECTION_STRING)

        dbname = client['cherifdb']
        coll_name = dbname['myclass']

        insertObject = []
        for x in coll_name.find({attribut: value}, {"_id": 0}):
            mycommon.myprint(x)
            user = x
            insertObject.append(JSONEncoder().encode(user))

        mycommon.myprint(" insertObject = "+ insertObject)
        return insertObject


    except Exception as e:
        mycommon.myprint(e)
        return False



def get_all_class():
    try:

        coll_name = dbname['myclass']

        insertObject = []
        for x in coll_name.find({'valide':'1', 'locked':'0'}, {"_id": 0}):
            mycommon.myprint(x)
            user = x
            insertObject.append(JSONEncoder().encode(user))

        #mycommon.myprint(" insertObject = ", insertObject)
        return True, insertObject
    except Exception as e:
        mycommon.myprint(e)
        return False, " Impossible de recuperer les formations"



'''
Cette fonction recherche les formations correspondant à un text
'''

def recherche_text_simple(diction):
    try:
        '''
        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
        # field_list.
        '''
        field_list = ['search_text', 'token', 'certif', 'support', 'type', 'lang','price']
        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list:
                mycommon.myprint(str(inspect.stack()[0][3])+" - :  Le champ  '" + val + "' n'existe pas, recherche annuléee")
                return False, "  Le champ  '" + val + "' n'existe pas, recherche annulée"

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = ['search_text', 'token']

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(str(inspect.stack()[0][3])+" - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " : La valeur '" + val + "' n'est pas presente dans liste "

        # recuperation des paramettre
        search_text = ""
        user_recid = ""
        token = ""
        critere_date = {}
        critere_string = ""
        new_diction = {}
        new_diction['token'] = ""

        if ("search_text" in diction.keys()):
            if diction['search_text']:
                search_text = diction['search_text']


        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']
                new_diction['token'] =  diction['token']

        certif_crit={}
        if ("certif" in diction.keys()):
            if diction['certif']:
                critere_date['certif'] = diction['certif']
                if (str(diction['certif']) != "NA"):
                    certif_crit['certif'] = diction['certif']
                    new_diction['certif'] = diction['certif']

        price_crit = {}
        if ("price" in diction.keys()):
            if diction['price']:
                critere_date['price'] = diction['price']
                if( str( diction['price']) != "NA"):
                    price_crit['price'] = diction['price']
                    new_diction['price'] = diction['price']


        support_crit = {}
        if ("support" in diction.keys()):
            if diction['support']:
                critere_date['support'] = diction['support']
                if (str(diction['support']) != "NA"):
                    support_crit['support'] = diction['support']
                    new_diction['support'] = diction['support']


        type_crit = {}
        if ("type" in diction.keys()):
            if diction['type']:
                critere_date['type'] = diction['type']
                if (str(diction['type']) != "NA"):
                    type_crit['type'] = diction['type']
                    new_diction['type'] = diction['type']


        lang_crit = {}
        if ("lang" in diction.keys()):
            if diction['lang']:
                critere_date['lang'] = diction['lang']
                if (str(diction['lang']) != "NA"):
                    lang_crit['lang'] = diction['lang']
                    new_diction['lang'] = diction['lang']

        '''
        /!\ Important : si le token est vide, alors c'est une recherche faite en mode non-connecté.
        on doit l'accepter.
        
        le controle de la validé du token est faite que ce dernier n'est pas vide.
        '''

        user_recid = "None"
        # Verification de la validité du token/mail dans le cas des user en mode connecté
        if ( len(str(token)) > 0 ):
            retval = mycommon.check_token_validity("", token)

            if retval is False :
                mycommon.myprint(str(inspect.stack()[0][3])+" - Le token n'est pas valide")
                return False, "Le token n'est pas valide"

            # Recuperation du recid de l'utilisateur
            user_recid = mycommon.get_user_recid_from_token(token)
            if user_recid is False:
                mycommon.myprint(str(inspect.stack()[0][3])+" - Impossible de recuperer le token de l'utilisateur")
                return False, " Impossible de desactiver l'objectif utilisateur"


        mycommon.myprint(" On recehrche la phrase +'" + search_text + "'")

        # Enregistrerment de la recherche
        retval, message = store_recherche(diction, user_recid)
        if (retval is False):
            return retval, message

        '''
        Verification si le texte de recherche contient un pattern de tips,
        c'est a dire une chaine de type : title:titre
        
        Si c'est le cas, nous sommes dans le cadre d'un recherche par type
        
        '''
        regexp = r"[\w\.-]+:\"[\w\s]*\""

        tips = re.findall(regexp, search_text, re.MULTILINE)
        nb_tips = len(tips)

        if( nb_tips > 0 ):
            mycommon.myprint(" Une recherche par tips a été identifiée")
            new_diction['token'] = token

            # Traitement pour chaque recherche par tips
            final_retval = False
            final_message = []
            insertObject = []

            for val in tips :
                val2 = val.replace('"', '')
                new_diction['search_text'] = val2
                print(" On va recherche : #####"+str(new_diction['search_text'] ))
                retval, message =  recherche_tips_ret_ref(new_diction)

                #print(" pour la recherche de : "+str(new_diction)+"  -- Voici le resultat "+str(message))
                if (retval == True ):
                    final_retval = True
                    final_message.append(message)


            print(" liste defitive des ref "+str(final_message))
            final_message2 = []

            for t in final_message:
                for y in t:
                    print( " unique = "+str(y))
                    final_message2.append(y)

            print(" YY = "+str(final_message2))


            coll_name = dbname['myclass']

            print(" Dans la recherch TIPS , les critère = " + str(certif_crit) + " la langue = " + str(
                lang_crit) + " price = " + str(price_crit)+" support = "+str(support_crit))


            for x in coll_name.find(({"$and": [{"external_code": {"$in": final_message2}},
                                               certif_crit, lang_crit, type_crit, price_crit, support_crit]})):
                mycommon.myprint(x)
                user = x
                insertObject.append(JSONEncoder().encode(user))

            # mycommon.myprint(" insertObject = ", insertObject)
            return True, insertObject


        tab_training = []
        tab_training = ela_index.ela_recherche_tokens(search_text)
        mycommon.myprint(" pour phrase : #" + search_text + "#, voici la liste des formations")
        mycommon.myprint(tab_training)

        coll_name = dbname['myclass']

        print(" Dans la recherch, les critère = "+str(certif_crit)+" la langue = "+str(lang_crit)+" price = "+str(price_crit))

        #ici ajouter tous les critère comme ci-dessous avec le support et le certif
        insertObject = []
        for x in coll_name.find(({"$and": [{"external_code": {"$in": tab_training}},
                                           certif_crit,lang_crit, type_crit,price_crit, support_crit ]})):
            mycommon.myprint(x)
            user = x
            insertObject.append(JSONEncoder().encode(user))

        # mycommon.myprint(" insertObject = ", insertObject)
        return True, insertObject

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible de lancer la recherche"






'''
Cette fonction enregistre les recherches faites par les user
dans la base de données.
L'idée principale est de stocker toutes les recherche, que soit en mode connecté ou en mode non connecté.
le difference se fera au niveau du mail de la personne.
structure du document dans la BDD (id, uer_mail, text_recherche, critere_recherce(JSON), valide)
la fontion prend en entrée un dictionnaire : 
- le texte
- la liste des critères; dont les valeurs exacts sont : 
    •	type 
    •	lang
    •	level
    •	dist  (distance) 
    •	price
    •	certif
    •	source 

Dans le cas ou le user a donnée un nom à la recherche, on ajoute le champ "name", ou s'il d'agit d'une mise à jour
le champ "id"
    •	name 
    •	id 
    
'''

def store_recherche(diction, user_recid=""):
    try:
        '''
        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
        # field_list.
        '''

        if (  len(str(user_recid)) <= 0 ):
            user_recid = 'None'  # by default


        field_list = ['search_text', 'token','id','type', 'lang', 'level', 'dist',
                      'price', 'certif', 'source', 'name','valide','certif', 'support','type']
        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list:
                mycommon.myprint("  Le champ  '" + val + "' n'existe pas, recherche annulée")
                return False, "  Le champ  '" + val + "' n'existe pas, recherche annulée"

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = ['search_text', 'token']

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(" : La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " : La valeur '" + val + "' n'est pas presente dans liste "


        # recuperation des paramettre
        mydata = {}
        mydata_id = ""
        my_token = ""

        if ("search_text" in diction.keys()):
            if diction['search_text']:
                mydata['search_text'] = diction['search_text']


        if ("user_mail" in diction.keys()):
            if diction['user_recid']:
                mydata['user_recid'] = diction['user_recid']

        if ("token" in diction.keys()):
            if diction['token']:
                my_token = diction['token']

        '''# Recuperation du recid de l'utilisateur
        user_recid = mycommon.get_user_recid_from_token(my_token)
        if user_recid is False:
            mycommon.myprint(" Impossible d'enregistrer la recherche de utilisateur")
            return False, " Impossible d'enregistrer la recherche de utilisateur"
        '''
        mydata['user_recid'] = user_recid

        if ("type" in diction.keys()):
            if diction['type']:
                mydata['type'] = diction['type']

        if ("lang" in diction.keys()):
            if diction['lang']:
                mydata['lang'] = diction['lang']

        if ("level" in diction.keys()):
            if diction['level']:
                mydata['level'] = diction['level']

        if ("dist" in diction.keys()):
            if diction['dist']:
                mydata['dist'] = diction['dist']

        if ("price" in diction.keys()):
            if diction['price']:
                mydata['price'] = diction['price']

        if ("certif" in diction.keys()):
            if diction['certif']:
                mydata['certif'] = diction['certif']

        if ("source" in diction.keys()):
            if diction['source']:
                mydata['source'] = diction['source']

        if ("name" in diction.keys()):
            if diction['name']:
                mydata['name'] = diction['name']


        if ("id" in diction.keys()):
            if diction['id']:
                mydata_id = diction['id']

        mydata['date_update'] = str(datetime.now())

        mydata['valide'] = "1" # By default
        if ("valide" in diction.keys()):
            if diction['valide']:
                mydata['valide'] = diction['valide']


        coll_name = dbname['user_recherche']

        # Si le champ "id" est renseigné, il s'agit d'une mis jour
        mycommon.myprint("on va stocker "+str(mydata)+"  id = "+str(mydata_id))

        if( len(str(mydata_id)) > 0 ):
            ret_val = coll_name.find_one_and_update({'_id': ObjectId(str(mydata_id)), 'valide': '1'},
                                                {"$set": mydata},
                                                    return_document=ReturnDocument.AFTER
                                                )

            if (ret_val and ret_val['_id']):
                nb_doc = str(ret_val['_id'])
                mycommon.myprint("La recherche a bien été mise à jour . Le Doc Id    = "+str(nb_doc))
                return True, "La recherche a bien été mise à jour"

            else:
                return False, "Impossible de mettre à jour a la recherche"

        else:
            ret_val = coll_name.insert_one(mydata)

            if ret_val and ret_val.inserted_id:
                nb_doc = ret_val.inserted_id
                mycommon.myprint("La recherche a été bien enregistrée. Id = '" + str(nb_doc)+"' ")
                return True, "La recherche a bien été mise à jour"
            else:
                return False, "Impossible d'enregistrer la recherche"


    except Exception as e:
        mycommon.myprint(e)
        return False, "Impossible d'enregistrer la recherche"




'''
Cette fonction prend une chaine de recherche en mode tips.
Si la fonction detecte un tips, alors elle retroune un 
1 - Un status = True et 
2 - Un tableau avec qui contient uniquement la reference externe de la formation


Si la fonction ne detecte pas de tips, elle retoure
1 - Un status = False
2 - Un tableau  = False
'''

def recherche_tips_ret_ref(diction):
    try:
        '''
        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
        # field_list.
        '''

        print(" RRRRR "+str(diction))
        field_list =  ['search_text', 'token', 'support', 'id',
                       'type', 'lang', 'level', 'dist', 'price',
                       'certif', 'source', 'name','valide']
        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list:
                mycommon.myprint(str(inspect.stack()[0][3])+" -  Le champ  '" + val + "' n'existe pas, recherche annulée")
                return False, "  Le champ  '" + val + "' n'existe pas, recherche annulée"

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = ['search_text', 'token']

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(str(inspect.stack()[0][3])+" -  La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " : La valeur '" + val + "' n'est pas presente dans liste "

        user_recid = "None"
        # recuperation du recId du user si le token est fourni.
        # si le token est vide, c'est que nous sommes sur une recherche en mode non connecté.
        if (len(str(diction['token'])) > 0):
            user_recid = mycommon.get_user_recid_from_token(str(diction['token']))
            if user_recid is False :
                mycommon.myprint(str(inspect.stack()[0][3])+" - Impossible de recuperer le recid du user")
                return False, "Impossible d'enregistrer la recherche"


        print(" #######  recherche tips, voici mon new diction"+str(diction))

        # Enregistrerment de la recherche
        retval, message = store_recherche(diction, user_recid)
        if( retval is False):
            return retval, message


        # recuperation des paramettre
        search_text = ""
        user_mail = ""
        token = ""

        if ("search_text" in diction.keys()):
            if diction['search_text']:
                search_text = diction['search_text']


        if( len(str(search_text)) <= 0 ):
            return False, False

        if (":" not in search_text):
            print(" La phrase ne contient pas de ':' ")
            return False, False

        print(" la chaine recu est "+search_text)
        chaine = search_text.split(":")

        val1 = str(chaine[0]).lower()

        print(" chaine[0] = "+val1)

        # Liste des tips acceptés
        tab_tips = ['title', 'description', 'desc',  'objectif', 'obj','trainer']

        min = 100
        my_tips = ""
        for val in tab_tips:
            retval = mycommon.levenshtein(val1, val)
            #print(" la distance entre '"+val1+"' et le mot  "+str(val)+" = "+str(retval))
            if( retval <= min ):
                min = retval
                my_tips = val

        if (min >= len(str(val1)) or min >= len(str(my_tips))  ):
            mycommon.myprint(str(inspect.stack()[0][3])+" -  le mot '"+val1+" ne correspond aucun tips, sorry")
            return False, " le mot '"+val1+" ne correspond aucun tips, sorry"


        mycommon.myprint(" Le tips recherché est "+my_tips+". Sa distance de Levenshtein ="+str(min))

        tab_ret = {}
        tab_ret['tips'] = str(my_tips)
        tab_ret['search_text'] = str(chaine[1]).lower()

        #return True, " le tips recherché est '"+my_tips+"' "

        tab_training = []
        tab_training = ela_index.ela_recherche_tokens_source_field(str(chaine[1]).lower(), str(my_tips) )

        mycommon.myprint(" pour phrase : #" + str(chaine[1]).lower() + "# , Pour le tips #"+ str(my_tips)+"#, voici la liste des formations")
        mycommon.myprint(tab_training)

        coll_name = dbname['myclass']

        return True, tab_training


        # ici lancer la recherche sur le champs title sss
        #return True, str(tab_ret)

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, "N/A"




'''
Cette fonction prend une chaine de recherche en mode tips.
Si la fonction detecte un tips, alors elle retroune un 
1 - Un status = True et 
2 - Un tableau avec 
    - Tab[0] : le champ sur lequel s'applique la recherche
    - Tab[0] : la chaine à rechercher

Si la fonction ne detecte pas de tips, elle retoure
1 - Un status = False
2 - Un tableau  = False
'''

def recherche_tips(diction):
    try:
        '''
        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
        # field_list.
        '''

        print(" RRRRR "+str(diction))
        field_list =  ['search_text', 'token', 'support', 'id',
                       'type', 'lang', 'level', 'dist', 'price',
                       'certif', 'source', 'name','valide']
        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list:
                mycommon.myprint(str(inspect.stack()[0][3])+" -  Le champ  '" + val + "' n'existe pas, recherche annulée")
                return False, "  Le champ  '" + val + "' n'existe pas, recherche annulée"

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = ['search_text', 'token']

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(str(inspect.stack()[0][3])+" -  La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " : La valeur '" + val + "' n'est pas presente dans liste "

        user_recid = "None"
        # recuperation du recId du user si le token est fourni.
        # si le token est vide, c'est que nous sommes sur une recherche en mode non connecté.
        if (len(str(diction['token'])) > 0):
            user_recid = mycommon.get_user_recid_from_token(str(diction['token']))
            if user_recid is False :
                mycommon.myprint(str(inspect.stack()[0][3])+" - Impossible de recuperer le recid du user")
                return False, "Impossible d'enregistrer la recherche"


        print(" #######  recherche tips, voici mon new diction"+str(diction))

        # Enregistrerment de la recherche
        retval, message = store_recherche(diction, user_recid)
        if( retval is False):
            return retval, message


        # recuperation des paramettre
        search_text = ""
        user_mail = ""
        token = ""

        if ("search_text" in diction.keys()):
            if diction['search_text']:
                search_text = diction['search_text']


        if( len(str(search_text)) <= 0 ):
            return False, False

        if (":" not in search_text):
            print(" La phrase ne contient pas de ':' ")
            return False, False

        print(" la chaine recu est "+search_text)
        chaine = search_text.split(":")

        val1 = str(chaine[0]).lower()

        print(" chaine[0] = "+val1)

        # Liste des tips acceptés
        tab_tips = ['title', 'description', 'desc',  'objectif', 'obj','trainer']

        min = 100
        my_tips = ""
        for val in tab_tips:
            retval = mycommon.levenshtein(val1, val)
            #print(" la distance entre '"+val1+"' et le mot  "+str(val)+" = "+str(retval))
            if( retval <= min ):
                min = retval
                my_tips = val

        if (min >= len(str(val1)) or min >= len(str(my_tips))  ):
            mycommon.myprint(str(inspect.stack()[0][3])+" -  le mot '"+val1+" ne correspond aucun tips, sorry")
            return False, " le mot '"+val1+" ne correspond aucun tips, sorry"


        mycommon.myprint(" Le tips recherché est "+my_tips+". Sa distance de Levenshtein ="+str(min))

        tab_ret = {}
        tab_ret['tips'] = str(my_tips)
        tab_ret['search_text'] = str(chaine[1]).lower()

        #return True, " le tips recherché est '"+my_tips+"' "

        tab_training = []
        tab_training = ela_index.ela_recherche_tokens_source_field(str(chaine[1]).lower(), str(my_tips) )

        mycommon.myprint(" pour phrase : #" + str(chaine[1]).lower() + "# , Pour le tips #"+ str(my_tips)+"#, voici la liste des formations")
        mycommon.myprint(tab_training)

        coll_name = dbname['myclass']

        insertObject = []
        for x in coll_name.find({"external_code": {"$in": tab_training}}, {"_id": 0}):
            mycommon.myprint(x)
            user = x
            insertObject.append(JSONEncoder().encode(user))

        # mycommon.myprint(" insertObject = ", insertObject)
        return True, insertObject


        # ici lancer la recherche sur le champs title sss
        #return True, str(tab_ret)

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, "N/A"



'''
Cette fonction retourne les recherche enregistrer d'un user donnée
'''
def get_stored_recherche(diction):
    try:

        '''
        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
        # field_list.
        '''
        field_list = ['token']
        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list:
                mycommon.myprint(str(inspect.stack()[0][3])+" -  Le champ  '" + val + "' n'existe pas, recherche annulée")
                return False, "  Le champ  '" + val + "' n'existe pas, recherche annulée"

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = [ 'token']

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(str(inspect.stack()[0][3])+" - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " : La valeur '" + val + "' n'est pas presente dans liste "

        # recuperation des paramettre
        search_text = ""
        user_recid = ""
        token = ""

        if ("search_text" in diction.keys()):
            if diction['search_text']:
                search_text = diction['search_text']

        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']


        # Verification de la validité du token/mail dans le cas des user en mode connecté
        if ( len(str(token)) <= 0):
            mycommon.myprint(str(inspect.stack()[0][3])+" -  Le token est vide")
            return False, " Impossible de recuperer historique de recherche"

        retval = mycommon.check_token_validity("", token)

        if retval is False:
            mycommon.myprint(str(inspect.stack()[0][3])+" -  Le token n'est pas valide")
            return False, " Impossible de recuperer l'historique de recherche"

        # Recuperation du recid du user
        user_recid = ""
        user_recid = mycommon.get_user_recid_from_token(token)
        if user_recid is False :
            mycommon.myprint(str(inspect.stack()[0][3])+" -  Impossible de recuperer le recid du user")
            return False, " Impossible de recuperer l'historique de recherche"


        coll_name = dbname['user_recherche']

        RetObject = []
        for retVal in coll_name.find({'user_recid': user_recid, 'valide':'1'}):
            mycommon.myprint(str(retVal))
            user = retVal
            RetObject.append(JSONEncoder().encode(user))

        return True, RetObject

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible de recuperer les recherches du user "

