from scripts.config.db_connection_obj import ConnectionObj
from scripts.logging.logger import logger
from scripts.utils.mongo_utility import MongoConnect


class CheckDuplicates(object):
    def __init__(self):
        try:
            self.mongo_obj = ConnectionObj.mongo_connection_obj
            if ConnectionObj.mongo_connection_obj is None:
                self.mongo_obj = MongoConnect()
        except Exception as e:
            logger.exception(str(e))

    def duplicate_name_check(self, db_name, coll_name, key_to_check, name, edit=False, unique_id_key=None,
                             unique_id_value=None,
                             is_deleted_key_check=False, is_deleted_key_name=None, is_deleted_key_value=None):
        """
        This function will check for duplicate name entries into the iLens system. This will perform case-sensitive search
        for the name. If any exceptions raised during the name check, it will consider as no duplicates found

        :param db_name: database name in which collection exists
        :param coll_name: collection name to perform duplicate name check
        :param key_to_check: key name to search for
                example: username to check users, tag_name to check tags, site_info.site_name to check site name
        :param name: user entered name
                example: Sudheesh as user name,
        :param edit: if user editing the name, pass this flag as True, else False
        :param unique_id_key: on edit of name, this key is mandatory to eliminate the edited record in DB while querying
                example: user_id for users, id for tags and units, user_role_id for user roles etc.,
        :param unique_id_value: on edit of name, this key is mandatory to eliminate the edited record in DB while querying
                example:user_6515 for users, unit_107 for units and tag_130 for tags, user_role_6518 for user roles etc.,
        :param is_deleted_key_check: if True, we will exclude deleted records in mongo query, else search for all records
                scenario: there are some cases where we will do soft delete in DB to retrieve data if something has deleted
                by mistaken
        :param is_deleted_key_name:  if is_deleted_key_check is True, pass the key name to exclude deleted records
                example: is_deleted is the key name for the channel_pipeline
        :param is_deleted_key_value: if is_deleted_key_check is True, pass the value to exclude deleted records
                example: False is the value for the channel_pipeline
        :return: False if  duplicates exists, else True
        """
        try:
            if edit:
                query = {key_to_check: {"$regex": f"^{name}$", '$options': 'i'},
                         unique_id_key: {"$nin": [unique_id_value]}}
            else:
                query = {key_to_check: {"$regex": f"^{name}$", '$options': 'i'}}
            if is_deleted_key_check:
                query.update({is_deleted_key_name: is_deleted_key_value})
            record_count = self.mongo_obj.find_count(json_data=query, database_name=db_name,
                                                     collection_name=coll_name)
            if record_count > 0:
                return True  # duplicate exists in the DB
            else:
                return False  # duplicates not found
        except Exception as e:
            logger.error(f" Error while checking for duplicate names in DB {e}")
            return False  # considering no duplicates found, if any exceptions raised
