"""
Ce fichier permet de gerer les droits d'acces des utilisateur au systeme

"""
import pymongo
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime
import prj_common as mycommon
import secrets
import inspect
import sys, os
import csv
import pandas as pd
from pymongo import ReturnDocument
import GlobalVariable as MYSY_GV
from math import isnan
import GlobalVariable as MYSY_GV
import ela_index_bdd_classes as eibdd
import email_mgt as email
import ast

"""
Ajouter & mise jour des acces d'un user
Cette fonction prend :
- token
- user_id (collection employee_id)
- tab_access ==> Tableau des droit d'acces
   ==> [{module_name: 'val', 'read':val, 'write':val}, {module_name: 'val', 'read':val, 'write':val}, ...]

"""
def Add_Update_User_Access_Right(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'user_id', 'tab_access']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', 'user_id', 'tab_access'  ]

        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, " Les informations fournies sont incorrectes",

        """
        Verification de l'identité et autorisation de l'entité qui
        appelle cette API
        """
        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']

        local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner

        # Verification de la validide du user_id
        is_user_existe_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id':ObjectId(str(diction['user_id'])),
                                                                                    'partner_recid':str(my_partner['recid']),
                                                                                    'valide':'1',
                                                                                    'locked':'0'})

        if( is_user_existe_count <= 0 ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'utilisateur est invalide ")
            return False, " L'utilisateur est invalide ",


        if( is_user_existe_count > 1 ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'identifiant utilisateur correspond à plusieurs personnes")
            return False, "L'identifiant utilisateur correspond à plusieurs personnes ",

        tab_access_data = diction['tab_access']

        tab_access_data = str(tab_access_data).replace("false", '"false"').replace("true", '"true"')
        tab_access_data = str(tab_access_data).replace('""false""', '"false"').replace('""true""', '"true"')

        tab_access = ast.literal_eval(tab_access_data)

        # Process de verification des infos d'acces
        for module_access in tab_access:

            if( "module_name" in module_access.keys() and "read" in module_access.keys() and "write" in module_access.keys() ):

                if( str(module_access['read']).lower().strip() not in ['true', 'false']  or str(module_access['write']).lower().strip() not in ['true', 'false']):
                    mycommon.myprint(
                        str(inspect.stack()[0][3]) + " - La matrice des droits est incorrecte (2) - Les champs 'read' et 'write' ne sont pas boolean")
                    return False, "La matrice des droits est incorrecte (2).Les champs 'read' et 'write' ne sont pas boolean",


                if( MYSY_GV.dbname['application_modules'].count_documents({'module_name':module_access['module_name']}) != 1  ):
                    mycommon.myprint( str(inspect.stack()[0][3]) + " - Module "+str(module_access['module_name'])+"  metier inconnue ")
                    return False, "Module "+str(module_access['module_name'])+"  metier inconnue ",


            else:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La matrice des droits est incorrecte")
                return False, "La matrice des droits est incorrecte ",

            #print(" ## ACCESS DATA ==> Mise à jour  ", module_access)




        # Process de mise à jour
        for module_access in tab_access:
            my_data = {}
            my_data['locked'] = '0'
            my_data['valide'] = '1'

            my_data['update_by'] = str(my_partner['_id'])
            my_data['date_update'] = str(datetime.now())
            my_data['module'] = module_access['module_name']


            if( str(module_access['read']).lower().strip() == "true"):
                my_data['read'] = True
            else:
                my_data['read'] = False

            if (str(module_access['write']).lower().strip() == "true"):
                my_data['write'] = True
            else:
                my_data['write'] = False



            my_data['partner_owner_recid'] = str(my_partner['recid'])
            my_data['user_id'] = str(diction['user_id'])


            result = MYSY_GV.dbname['user_access_right'].find_one_and_update(
                {'module_name':module_access['module_name'], 'user_id':str(diction['user_id'])},
                {"$set": my_data},
                upsert=True,
                return_document=ReturnDocument.AFTER
            )

            if (result is None or "_id" not in result.keys()):
                mycommon.myprint(
                    " Impossible  mettre à jour les droits d'acces  du user_id" + str(diction['user_id']))
                return False, " Impossible  mettre à jour les droits d'acces  "



        return True, " Les droits d'accès ont été correctement mis à jour"

    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 d'ajouter la ressource "

"""
Recuperation de la matrice de droit d'un user (ressource_humaine_id)
"""
def Get_Matrix_Acces_Right(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'user_id']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', 'user_id'  ]

        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, " Les informations fournies sont incorrectes",

        """
        Verification de l'identité et autorisation de l'entité qui
        appelle cette API
        """
        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']

        local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner


        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['application_modules'].find({'valide':'1', 'locked':'0'}):
            user = retval
            user['id'] = str(val_tmp)

            user['read'] = False
            user['write'] = False

            # Pour le module en question, on va aller recuperer les eventuels droits de l'utilisateur
            user_acces_right_qry = {'valide':'1', 'locked':'0', 'user_id':str(diction['user_id']),
                                                                              'partner_owner_recid':str(my_partner['recid']),
                                                                              'module':str(retval['module_name'])}


            #print(" ### user_acces_right_qry = ", user_acces_right_qry)
            user_acces_right = MYSY_GV.dbname['user_access_right'].find_one(user_acces_right_qry)

            if( user_acces_right is not None ):
                if( 'read' in user_acces_right.keys()):
                    user['read'] = user_acces_right['read']
                else:
                    user['read'] = False

                if ('write' in user_acces_right.keys()):
                    user['write'] = user_acces_right['write']
                else:
                    user['write'] = False


            #print(" ### user_acces_right - user = ", user)
            val_tmp = val_tmp + 1
            RetObject.append(mycommon.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 récupérer la matrice des droits "


"""
Recuperation de la matrice des acces associé à un profil utilisateur (ex : enseignant, directeur, etc
"""


def Get_Matrix_Acces_Right_By_Profil(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'profile_name']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', 'profile_name']

        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, " Les informations fournies sont incorrectes",

        """
        Verification de l'identité et autorisation de l'entité qui
        appelle cette API
        """
        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']

        local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner


        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['application_modules'].find({'valide': '1', 'locked': '0'}):
            user = retval
            user['id'] = str(val_tmp)

            user['read'] = False
            user['write'] = False

            # Pour le module en question, on va aller recuperer les eventuels droits de l'utilisateur
            user_acces_right_qry = {'valide': '1', 'locked': '0', 'profile_name': str(diction['profile_name']),
                                    'partner_owner_recid': str(my_partner['recid']),
                                    'module': str(retval['module_name'])}

            # print(" ### user_acces_right_qry = ", user_acces_right_qry)
            user_acces_right = MYSY_GV.dbname['user_access_right'].find_one(user_acces_right_qry)

            if (user_acces_right is not None):
                if ('read' in user_acces_right.keys()):
                    user['read'] = user_acces_right['read']
                else:
                    user['read'] = False

                if ('write' in user_acces_right.keys()):
                    user['write'] = user_acces_right['write']
                else:
                    user['write'] = False

            # print(" ### user_acces_right - user = ", user)
            val_tmp = val_tmp + 1
            RetObject.append(mycommon.JSONEncoder().encode(user))

        print(" RetObject = ", RetObject)
        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 récupérer la matrice des droits "
