"""
Module for alarm configuration
"""
import json
import re
from copy import deepcopy
from datetime import datetime

from redis import Redis

from scripts.config import app_configuration
from scripts.config import app_constants
from scripts.config.app_constants import DBMapping as Dbm
from scripts.config.app_constants import MongoMetadata, AlarmTypes
from scripts.config.db_connection_obj import ConnectionObj
from scripts.logging.logger import logger
from scripts.utils.alarm_time_utility import AlarmTimeUtility
from scripts.utils.config_utlity import NewConfigUtility
from scripts.utils.duplicate_name_check import CheckDuplicates
from scripts.utils.get_new_id import GetNewId
from scripts.utils.mongo_utility import MongoConnect


class AlarmConfigurationHandler:
    def __init__(self):
        self.mongo_obj = ConnectionObj.mongo_connection_obj
        if ConnectionObj.mongo_connection_obj is None:
            self.mongo_obj = ConnectionObj.mongo_connection_obj = MongoConnect()
        self.next_id = GetNewId()
        self.utility = NewConfigUtility()
        self.alarm_redis = Redis(host=app_configuration.redis_host, port=app_configuration.redis_port,
                                 db=app_configuration.alarms_redis_db)
        self.alarm_time_util = AlarmTimeUtility()
        self.dev_cache = dict()
        self.dup_check = CheckDuplicates()

    def create_alarm_configuration(self, input_data):
        final_json = {"status": "failed", "message": "Failed to create alarm configuration"}
        try:
            user_id = self.utility.get_usr_id(input_data)
            if input_data["id"] == "new":
                project_id = input_data["project_id"]
                if "data" in input_data:
                    input_data = input_data["data"]
                alarm_name_exists = self.dup_check.duplicate_name_check(db_name=Dbm.mongo_db_name,
                                                                        coll_name=Dbm.alarm_configuration,
                                                                        key_to_check="alarmName",
                                                                        name=input_data["alarmName"])
                if alarm_name_exists is True:
                    return {"status": "failed", "message": "alarm name already exists"}
                new_id = "alarm_configuration_" + self.next_id.get_next_id("alarm_configuration")
                input_data['id'] = new_id
                input_data["project_id"] = project_id
                input_data["created_by"] = user_id
                json_to_redis = self.make_json_to_push_into_redis(alarm_data=input_data)
                self.insert_into_redis(json_to_redis=json_to_redis)
                input_data["selectedTags"] = json_to_redis.get("selectedTags")
                self.mongo_obj.insert_one(input_data, Dbm.mongo_db_name, Dbm.alarm_configuration)
                final_json["status"] = "success"
                final_json["message"] = "Alarm saved successfully."
            else:
                query = {"id": input_data["id"]}
                id = input_data["id"]
                project_id = input_data["project_id"]
                prev_tags = input_data["previousTags"]
                input_data = input_data["data"]
                alarm_name_exists = self.dup_check.duplicate_name_check(db_name=Dbm.mongo_db_name,
                                                                        coll_name=Dbm.alarm_configuration,
                                                                        key_to_check="alarmName",
                                                                        name=input_data["alarmName"],
                                                                        edit=True, unique_id_key="id",
                                                                        unique_id_value=id)
                if alarm_name_exists is True:
                    return {"status": "failed", "message": "alarm name already exists"}
                input_data["project_id"] = project_id
                input_data["edited"] = "true"
                input_data["created_by"] = user_id
                json_to_redis = self.make_json_to_push_into_redis(alarm_data=input_data)
                input_data["selectedTags"] = json_to_redis.get("selectedTags")
                # remove removed tags from conditions
                status = self.remove_removed_tags(prev_tags, input_data["selectedTags"], input_data["id"])
                if status:
                    logger.debug("Removed unused tags")
                else:
                    logger.debug("Error while deleting unwanted keys from redis")
                self.insert_into_redis(json_to_redis=json_to_redis)
                self.mongo_obj.update_one(
                    db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration, query=query,
                    set_json=input_data, upsert=True)
                final_json["status"] = "success"
                final_json["message"] = "Alarm  saved successfully"
        except Exception as e:
            logger.exception("Exception->%s" % str(e))
        return final_json

    def get_alarm_configuration(self, input_data):
        final_json = {"status": "failed", "message": "Failed to get the alarm configuration data.",
                      "data": {"headerContent": {}, "bodyContent": ""}}
        try:
            header_content = {"alarmPriorityTypes": [], "tags": [], "thresholds": [], "usersAndUsersGroup": [],
                              "commandTags": [], "notification_type": [], "alarmTypes": []}
            alarm_types = self.mongo_obj.find_with_condition(json_data={"content_type": "alarm_types"},
                                                             database_name=Dbm.mongo_db_name,
                                                             collection_name=MongoMetadata.static_content)
            if alarm_types.count() == 0:
                self.mongo_obj.update_one(query={"content_type": "alarm_types"},
                                          db_name=Dbm.mongo_db_name,
                                          collection_name=MongoMetadata.static_content,
                                          upsert=True,
                                          set_json={"data": AlarmTypes.alarm_types, "content_type": "alarm_types"})
                alarm_types = [{"data": AlarmTypes.alarm_types, "content_type": "alarm_types"}]
            header_content['alarmTypes'] = alarm_types[0]["data"]
            alarm_priority_list = self.mongo_obj.find_many(
                db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_priority, query_json={}, search_option={"_id": 0})
            for each_priority_type in alarm_priority_list:
                try:
                    header_content["alarmPriorityTypes"].append({
                        "value": each_priority_type["id"], "label": each_priority_type["name"],
                        "color": each_priority_type["priorityColor"]})
                except Exception as e:
                    logger.exception("Exception while iterating the alarm priority type:" + str(e))
            alarm_notify_type_data = self.mongo_obj.find_one(
                db_name=Dbm.mongo_db_name, collection_name=Dbm.constants, query={"content_type": "alarm_notify_type"},
                search_json={"_id": 0, "data": 1})["data"]
            for each_alarm_notify_type in alarm_notify_type_data:
                try:
                    header_content["notification_type"].append({"value": each_alarm_notify_type["id"],
                                                                "label": each_alarm_notify_type["name"]})
                except Exception as e:
                    logger.exception(" Exception while iterating the alarm notify list:" + str(e))
            threshold_data = self.mongo_obj.find_many(
                db_name=Dbm.mongo_db_name, collection_name=Dbm.thresholds, query_json={}, search_option={"_id": 0})
            for each_threshold in threshold_data:
                try:
                    header_content["thresholds"].append({"value": each_threshold["threshold_id"],
                                                         "label": each_threshold["name"]})
                except Exception as e:
                    logger.exception(str(e))
            access_group_data = self.mongo_obj.search_record_by_query2(
                db_name=Dbm.mongo_db_name, collection_name=Dbm.access_group,
                query_json={"project_id": input_data["project_id"]}, search_option={"_id": 0})
            for each_access_group in access_group_data:
                try:
                    header_content["usersAndUsersGroup"].append({
                        "value": each_access_group["access_group_id"], "type": "access_group",
                        "label": each_access_group["access_group"]})
                except Exception as e:
                    logger.exception("Exception while iterating work group data:" + str(e))
            users_data = self.mongo_obj.search_record_by_query2(
                db_name=Dbm.mongo_db_name, collection_name=Dbm.user,
                query_json={"project_id": input_data["project_id"]}, search_option={"_id": 0})
            for each_user in users_data:
                try:
                    header_content["usersAndUsersGroup"].append({"value": each_user["user_id"], "type": "user",
                                                                 "label": each_user["username"]})
                except Exception as e:
                    logger.exception("Exception while iterating users list:" + str(e))
            if input_data["id"] == "new":
                final_json["data"]["headerContent"] = header_content
                final_json["status"] = 'success'
                final_json["message"] = "Alarm configuration data loaded successfully"
            else:
                final_json["data"]["headerContent"] = header_content
                final_json["data"]["bodyContent"] = self.mongo_obj.find_one(
                    db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration, query={"id": input_data["id"]},
                    search_json={"_id": 0})
                final_json["status"] = 'success'
                final_json["message"] = "Alarm configuration data loaded successfully"

        except Exception as e:
            logger.exception(" Exception while fetching alarm:" + str(e))
        return final_json

    def get_alarm_list(self, input_data):
        final_json = {"data": [], "body_content": [], "header_content": {}, "status": "failed",
                      "message": "Failed to get the alarm list"}
        try:
            alarm_configuration_data = self.mongo_obj.search_record_by_query2(
                db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration,
                query_json={"project_id": input_data["project_id"]}, search_option={"_id": 0})
            final_json["body_content"] = alarm_configuration_data
            final_json["status"] = 'success'
            final_json["message"] = "Alarm list fetched successfully"
        except Exception as e:
            logger.exception("Exception while fetching alarm list:" + str(e))
        return final_json

    def delete_alarm_configuration(self, input_data):
        final_json = {"status": "failed", "message": "Failed to delete alarm"}
        try:
            alarm_data = self.mongo_obj.find_one(db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration,
                                                 query={"id": input_data["id"]})
            self.remove_alarm_from_redis(alarm_data=alarm_data)
            self.mongo_obj.delete_one_record(db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration,
                                             query_json={"id": input_data["id"]})
            final_json["status"] = "success"
            final_json["message"] = "Alarm deleted successfully"
        except Exception as e:
            logger.exception("Unable to delete alarm:" + str(e))
        return final_json

    def alarm_configuration_tags(self, input_data):
        final_json = {"data": [], "status": "failed", "message": "Failed to get the alarm configuration tags."}
        try:
            site_data = self.mongo_obj.search_record_by_query2(
                db_name=Dbm.mongo_db_name, collection_name=Dbm.site_conf,
                query_json={"site_id": {"$in": list(input_data["data"].keys())}})
            tag_mapping = self.utility.fetch_tag()
            for each_site in site_data:
                try:
                    main_list = ["site"]
                    compo_map = {each_site["site_id"]: each_site["site_name"]}
                    for each_component in input_data["data"][each_site["site_id"]]:
                        try:
                            if each_component["node_id"].split("_")[0] == "site":
                                for each_tag in each_site["site_info"]["tags"]:
                                    try:
                                        high_performance = False
                                        if "high_performance" in each_tag:
                                            high_performance = each_tag["high_performance"]
                                        final_json["data"].append(
                                            {"value": each_component["node_id"] + "$" + each_tag["value"],
                                             "label": each_site["site_name"] + ":" + tag_mapping[each_tag["value"]],
                                             "high_performance": high_performance})
                                    except Exception as e:
                                        logger.exception(str(e))
                            else:
                                for i in each_site[each_component["node_id"].split("_")[0]]:
                                    try:
                                        if i[each_component["node_id"].split("_")[0] + "_id"] == \
                                                each_component["node_id"]:
                                            component = each_component["id"].split("$")
                                            tag_name = []
                                            for each in component:
                                                try:
                                                    if each.split("_")[0] not in main_list:
                                                        main_list.append(each.split("_")[0])
                                                        for j in each_site[each.split("_")[0]]:
                                                            try:
                                                                compo_map[j[each.split("_")[0] + "_id"]] = j[
                                                                    each.split("_")[0] + "_name"]
                                                            except Exception as e:
                                                                logger.exception(str(e))
                                                    tag_name.append(compo_map[each])
                                                except Exception as e:
                                                    logger.exception(str(e))
                                            for each_tag in i["tags"]:
                                                try:
                                                    high_performance = False
                                                    if "high_performance" in each_tag:
                                                        high_performance = each_tag["high_performance"]
                                                    final_json["data"].append(
                                                        {"value": each_component["id"] + "$" + each_tag["value"],
                                                         "label": ">".join(tag_name) + ":" + tag_mapping[
                                                             each_tag["value"]],
                                                         "high_performance": high_performance})
                                                except Exception as e:
                                                    logger.exception(str(e))
                                    except Exception as e:
                                        logger.exception("Exception->%s" % str(e))
                        except Exception as e:
                            logger.exception(str(e))
                except Exception as e:
                    logger.exception(str(e))
            final_json["status"] = "success"
            final_json["message"] = "Tags fetched successfully"
        except Exception as e:
            logger.exception("Exception->%s" % str(e))
        return final_json

    def alarm_enable_disable(self, input_data):
        final_json = {"status": "failed", "message": "Failed to enable/disable alarm."}
        try:
            if "enabled" in self.mongo_obj.find_one(db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration,
                                                    query={"id": input_data["id"]}):
                self.mongo_obj.update_one(db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration,
                                          query={"id": input_data["id"]},
                                          set_json={"$set": {"enabled": input_data["enabled"]}})
                alarm_name = self.mongo_obj.find_one(db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration,
                                                     query={"id": input_data["id"]},
                                                     search_json={"_id": 0})["alarmName"]
                final_json["status"] = "success"
                if input_data["enabled"] is True:
                    final_json["message"] = alarm_name + " enabled successfully"
                else:
                    final_json["message"] = alarm_name + " disabled successfully"
            else:
                alarm_name = self.mongo_obj.find_one(db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration,
                                                     query={"id": input_data["id"]}, search_json={"_id": 0})[
                    "alarmName"]
                self.mongo_obj.update_one(db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_configuration,
                                          query={"id": input_data["id"]},
                                          set_json={"$set": {"enabled": input_data["enabled"]}}, upsert=True)
                final_json["status"] = "success"
                if input_data["enabled"] is True:
                    final_json["message"] = alarm_name + " enabled successfully"
                else:
                    final_json["message"] = alarm_name + " disabled successfully"
        except Exception as e:
            logger.exception("Exception->%s" % str(e))
        return final_json

    def make_json_to_push_into_redis(self, alarm_data):
        """
        it will make jsong to push into redis
        """
        try:
            selected_tags = []
            threshold_dict = {}
            threshold_data = self.mongo_obj.find_many(query_json=alarm_data,
                                                      db_name=Dbm.mongo_db_name,
                                                      collection_name=Dbm.thresholds)
            for each_threshold in threshold_data:
                try:
                    threshold_dict[each_threshold["threshold_id"]] = each_threshold["value"]
                except Exception as e:
                    logger.exception(" Exception while iterating threshold data:" + str(e))
            final_threshold_dict = {}
            for each_rule_set in alarm_data["ruleSets"]:
                try:
                    for each_rule in each_rule_set["rules"]:
                        try:
                            selected_tags.append(each_rule["leftHandSide"]["tag"])
                            if each_rule["rightHandSide"]["tag"]:
                                selected_tags.append(each_rule["leftHandSide"]["tag"])
                            if each_rule["rightHandSide"]["threshold"]:
                                final_threshold_dict.update({each_rule["rightHandSide"]["threshold"]: threshold_dict[
                                    each_rule["rightHandSide"]["threshold"]]})
                        except Exception as e:
                            logger.exception(str(e))
                except Exception as e:
                    logger.exception(str(e))
            selected_tags = list(set(selected_tags))
            temp_json = {"alarmName": alarm_data["alarmName"], "alarmType": alarm_data["alarmType"],
                         "isTypeIsAlarm": alarm_data["isTypeIsAlarm"], "devices": alarm_data["devices"],
                         "ruleSets": alarm_data["ruleSets"],
                         "ruleSetAndOrOperationData": alarm_data["ruleSetAndOrOperationData"],
                         "levels": alarm_data["levels"], "enabled": alarm_data["enabled"], "id": alarm_data["id"],
                         "selectedTags": selected_tags,
                         "threshold_dict": final_threshold_dict}
            if len(selected_tags) > 1:
                temp_json["multiTag"] = True
            else:
                temp_json["multiTag"] = False
            return temp_json
        except Exception as e:
            logger.exception("unable to make json to push to redis:" + str(e))

    def insert_into_redis(self, json_to_redis):
        """
        this function will insert rule data into redis
        """
        try:
            conn_obj = self.alarm_redis
            for each_selected_tag in json_to_redis["selectedTags"]:
                try:
                    conn_obj.hset(each_selected_tag, json_to_redis["id"], json.dumps(json_to_redis))
                except Exception as e:
                    logger.exception(str(e))
        except Exception as e:
            logger.exception("unable to insert alarm into redis:" + str(e))

    def duplicate_alarm_name_check(self, input_data, edit_flag=False):
        """
        this will check whether that rule already exists while creations
        """
        if edit_flag:
            query = {"alarmName": input_data["alarmName"], "id": {"$nin": [input_data["id"]]}}
        else:
            query = {"alarmName": input_data["alarmName"]}
        exists = self.mongo_obj.find_one(query=query, db_name=Dbm.mongo_db_name,
                                         collection_name=Dbm.alarm_configuration)
        if exists is not None:
            return True
        else:
            return False

    def remove_alarm_from_redis(self, alarm_data):
        try:
            conn_obj = self.alarm_redis
            selected_tags = []
            for each_rule_set in alarm_data["ruleSets"]:
                try:
                    for each_rule in each_rule_set["rules"]:
                        try:
                            selected_tags.append(each_rule["leftHandSide"]["tag"])
                            if each_rule["rightHandSide"]["tag"]:
                                selected_tags.append(each_rule["leftHandSide"]["tag"])
                        except Exception as e:
                            logger.exception(str(e))
                except Exception as e:
                    logger.exception(str(e))
            selected_tags = list(set(selected_tags))
            for each_selected_tag in selected_tags:
                try:
                    conn_obj.hdel(each_selected_tag, alarm_data["id"])
                except Exception as e:
                    logger.exception(str(e))
        except Exception as e:
            logger.exception("Unable to clear REDIS cache:" + str(e))

    def get_alarm_work_bench(self, input_data):
        final_json = {"status": "failed", "message": "failed"}
        try:
            logger.debug(input_data)
            user_id = self.utility.get_usr_id(input_data)
            final_json["headerCols"] = self.mongo_obj.find_one(
                Dbm.mongo_db_name, Dbm.constants, {"type": "triggered_alarms_header"}, {"_id": 0})["data"]
            final_json["alarms"] = []

            if input_data["time_range"]["filter_by"] == "interval" and input_data["time_range"]["interval"] in \
                    app_constants.AlarmTimeMapping.allowed_input_data_type:
                start_date, end_date = self.alarm_time_util.parse_relative_time_data(input_data["time_range"][
                                                                                         "interval"])
            elif input_data["time_range"]["filter_by"] == "range":
                start_date = datetime.strptime(input_data["time_range"]["range"]["from"] + ".000000",
                                               "%d-%m-%Y %H:%M:%S.%f")
                end_date = datetime.strptime(input_data["time_range"]["range"]["to"] + ".000000",
                                             "%d-%m-%Y %H:%M:%S.%f")
            else:
                final_json["message"] = "Invalid Time Range Filters"
                return final_json
            alert_priority = input_data["alert_priority"]
            alert_state = input_data["alert_state"]
            alarm_dict = dict()
            try:
                for each_alarm in self.mongo_obj.fetch_all(Dbm.mongo_db_name, Dbm.alarm_priority):
                    alarm_dict[each_alarm["id"]] = {"name": each_alarm["name"], "colour": each_alarm["priorityColor"]}
            except Exception as e:
                logger.exception("Exception in get_alarm_dict" + str(e))
            qry = {}
            if alert_state == "all" and alert_priority == "all":
                qry = {}
            if alert_state == "not_acknowledge":
                qry["acknowledge"] = False
            if alert_state == "acknowledge":
                qry["acknowledge"] = True
            if alert_priority != "all":
                _id = self.mongo_obj.find_one(Dbm.mongo_db_name, Dbm.alarm_priority,
                                              {"unique_name": str(alert_priority).lower()})
                if _id:
                    qry["priority"] = _id["id"]
            project_id = input_data["project_id"]
            qry["project_id"] = project_id
            print(qry)
            for each_triggered_alarm in ConnectionObj.mongo_connection_obj. \
                    search_record_by_query2(Dbm.ilens_events, Dbm.triggered_alarms, qry, {"_id": 0}):
                if "show_data_viz" in each_triggered_alarm:
                    show_data_viz = True
                else:
                    show_data_viz = False
                if "." in str(each_triggered_alarm["start_time"]):
                    alarm_time = datetime.strptime(
                        str(each_triggered_alarm["start_time"]), "%Y-%m-%d %H:%M:%S.%f")
                else:
                    alarm_time = datetime.strptime(
                        str(each_triggered_alarm["start_time"]), "%Y-%m-%d %H:%M:%S")
                if start_date <= alarm_time <= end_date:
                    try:
                        user_alarm_flag = self.get_user_alarm_flag(each_triggered_alarm, user_id)
                        if not user_alarm_flag:
                            continue
                        via = self.get_notification_profile(each_triggered_alarm)
                        via = via.rstrip(", ")
                        temp_json = self.get_alarm_json(each_triggered_alarm, alarm_dict)
                        temp_json["via"] = via
                        temp_json["show_data_viz"] = show_data_viz
                        final_json["alarms"].append(temp_json)
                    except Exception as e:
                        logger.exception(str(e))
                        continue
            try:
                sorted_alarms = sorted(final_json["alarms"],
                                       key=lambda x: datetime.strptime(x["timeStamp"], "%Y-%m-%d %H:%M:%S"),
                                       reverse=True)
                final_json["alarms"] = sorted_alarms
            except Exception as e:
                logger.exception("Exception while sorting alarms :" + str(e))

            final_json["status"] = "success"
            final_json["message"] = "success"
        except Exception as e:
            logger.exception(str(e))
        return final_json

    def get_alarm_work_bench_updated(self, input_data):
        final_json = {"status": "failed", "message": "failed", "data": {}}
        try:
            logger.debug(f"Input data for fetching alarms : {input_data}")
            map_json = {"timeStamp": "start_time", "tag_name": "tag_id_list", "alert_condition": "alarm_condition"}
            final_json["data"] = deepcopy(app_constants.AlarmTable.alarm_table_header)

            # Fetch tag data
            tag_mapping, tag_mapping_for_tag_header = self.get_tag_mapping()

            start_date, end_date = self.get_start_date_and_end_date(input_data=input_data)
            alarm_dict = self.get_alarm_priority_list()

            # Fetch user data
            input_data_copy = deepcopy(input_data)
            user_id = self.utility.get_usr_id(input_data)
            # Get info for pagination
            records_to_skip = int(input_data["records"]) * (int(input_data["page"]) - 1)
            limit = int(input_data['records'])

            # Prepare query to filter
            query_to_filter = {}
            project_id = input_data["project_id"]
            query_to_filter["project_id"] = project_id
            start_date_new = start_date.strftime("%Y-%m-%d %H:%M:%S.%f")
            end_date_new = end_date.strftime("%Y-%m-%d %H:%M:%S.%f")
            query_to_filter["start_time"] = {"$gte": start_date_new, "$lte": end_date_new}

            # update query with the user selected filters
            query_to_filter = self.get_query_to_filter(query_to_filter=query_to_filter, input_data=input_data,
                                                       map_json=map_json, tag_mapping=tag_mapping)
            table_data = list(self.mongo_obj.find_with_sort_and_skip(db_name=Dbm.ilens_events,
                                                                     sort_json=[("start_time_in_epoch", -1)],
                                                                     query_json=query_to_filter,
                                                                     collection_name=Dbm.triggered_alarms,
                                                                     limit=limit, skip=records_to_skip,
                                                                     search_option={'_id': 0}))
            # Check if data exists for the next page
            next_page_records = int(input_data["records"]) * (int(input_data["page"]))
            next_page_data = list(self.mongo_obj.find_with_sort_and_skip(db_name=Dbm.ilens_events,
                                                                         sort_json=[("start_time_in_epoch", -1)],
                                                                         query_json=query_to_filter,
                                                                         collection_name=Dbm.triggered_alarms,
                                                                         limit=limit, skip=next_page_records,
                                                                         search_option={'_id': 0}))
            total_records_for_query = {}
            if len(next_page_data):
                final_json["data"]['endofrecords'] = False

                # Fetch total records for the selected filters
                total_records_for_query = list(self.mongo_obj.find_with_condition(json_data=query_to_filter,
                                                                                  database_name=Dbm.ilens_events,
                                                                                  collection_name=Dbm.triggered_alarms))
            final_json["data"]['total_no'] = len(total_records_for_query)

            for each_triggered_alarm in table_data:
                device_names = ""
                devices = ""
                de_id_list = each_triggered_alarm["device_instance_id"][:-1].split(",")
                for each_dev in de_id_list:
                    each_dev = each_dev.split("$tag")[0]
                    devices = devices + each_dev + ","
                    if each_dev in self.dev_cache:
                        device_names = device_names + str(self.dev_cache[each_dev]) + ","
                    else:
                        name = self.get_component_name(each_dev)
                        device_names = device_names + name + ","
                        self.dev_cache[each_dev] = name

                # Add tags and deviceNames in header options

                tag = each_triggered_alarm["tag_id_list"][0].split("$")[-1]
                tag_header = {
                    "label": tag_mapping_for_tag_header[tag],
                    "value": tag_mapping_for_tag_header[tag]
                }
                if tag_header not in final_json["data"]["tableData"]["headerContent"][4]["options"]:
                    final_json["data"]["tableData"]["headerContent"][4]["options"].append(tag_header)
                device_header = {
                    "label": device_names[:-1],
                    "value": device_names[:-1]
                }
                if device_header not in final_json["data"]["tableData"]["headerContent"][3]["options"]:
                    final_json["data"]["tableData"]["headerContent"][3]["options"].append(device_header)

                if "show_data_viz" in each_triggered_alarm:
                    show_data_viz = True
                else:
                    show_data_viz = False
                try:
                    user_alarm_flag = self.get_user_alarm_flag(each_triggered_alarm, user_id)
                    if not user_alarm_flag:
                        continue
                    via = self.get_notification_profile(each_triggered_alarm)
                    via = via.rstrip(", ")
                    temp_json, new_alert_list = self.get_alarm_json_updated(each_triggered_alarm, alarm_dict)
                    # Add AlarmCondition header
                    alarm_header = {
                        "label": new_alert_list,
                        "value": each_triggered_alarm["alarm_condition"]
                    }

                    if alarm_header not in final_json["data"]["tableData"]["headerContent"][-1]["options"]:
                        final_json["data"]["tableData"]["headerContent"][-1]["options"].append(alarm_header)
                    temp_json["via"] = via
                    temp_json["show_data_viz"] = show_data_viz
                    final_json["data"]["tableData"]["bodyContent"].append(temp_json)

                except Exception as e:
                    logger.error(f"Error occurred while fetching alarm data : {str(e)}", exc_info=True)
                    continue
            final_json = self.remove_unwanted_devices(input_data_copy=input_data_copy, final_json=final_json)
            # final_json["data"]["tableData"]["bodyContent"] = self.get_sorted_alarm_json(final_json=final_json)

            final_json["status"] = "success"
            final_json["message"] = "success"
        except Exception as e:
            logger.error(str(e), exc_info=True)
        return final_json

    @staticmethod
    def remove_unwanted_devices(input_data_copy, final_json):
        """
        # Filter deviceNames (If deviceNames exists in input_data[filters])

        :param input_data_copy:
        :param final_json:
        :return:
        """
        try:
            unwanted_device_names = []
            if "filters" in input_data_copy and len(input_data_copy['filters'].keys()):
                for each_filter in input_data_copy['filters']:
                    if input_data_copy['filters'][each_filter] is not None \
                            and input_data_copy['filters'][each_filter] != "":
                        if each_filter == "deviceNames":
                            for index, each in enumerate(final_json["data"]["tableData"]["bodyContent"]):
                                if each["deviceNames"] == input_data_copy['filters'][each_filter]:
                                    continue
                                else:
                                    unwanted_device_names.append(each)
            for each in unwanted_device_names:
                if each in final_json["data"]["tableData"]["bodyContent"]:
                    final_json["data"]["tableData"]["bodyContent"].remove(each)
        except Exception as e:
            logger.exception(f" while removing devices {e}")
        return final_json

    @staticmethod
    def get_sorted_alarm_json(final_json):
        try:
            sorted_alarms = sorted(final_json["data"]["tableData"]["bodyContent"],
                                   key=lambda x: datetime.strptime(x["timeStamp"], "%Y-%m-%d %H:%M:%S"),
                                   reverse=True)
            return sorted_alarms
        except Exception as e:
            logger.exception(f" while sorting the alarms {e}")

    def get_query_to_filter(self, query_to_filter, input_data, map_json, tag_mapping):
        try:
            if "filters" in input_data and len(input_data['filters'].keys()):
                for each_filter in input_data['filters']:
                    if input_data['filters'][each_filter] is not None and input_data['filters'][each_filter] != "":
                        if each_filter == "deviceNames":
                            continue

                        elif each_filter == "tag_name":
                            query_to_filter[map_json[each_filter]] = {
                                '$regex': tag_mapping[input_data['filters'][each_filter]],
                                '$options': 'i'}

                        elif each_filter == "priority":
                            if input_data['filters'][each_filter] != "all":
                                _id = self.mongo_obj.find_one(Dbm.mongo_db_name, Dbm.alarm_priority,
                                                              {"unique_name": str(
                                                                  input_data['filters'][each_filter]).lower()})
                                if _id:
                                    query_to_filter["priority"] = _id["id"]
                        elif each_filter == "alert_condition":
                            query_to_filter[map_json[each_filter]] = input_data['filters'][each_filter]

                        # Removing this as this is no longer required
                        # elif each_filter == "timeStamp":
                        #     start_date = input_data['filters'][each_filter][0] / 1000
                        #     start_date = datetime.fromtimestamp(start_date).strftime("%Y-%m-%d %H:%M:%S.%f")
                        #     end_date = input_data['filters'][each_filter][1] / 1000
                        #     end_date = datetime.fromtimestamp(end_date).strftime("%Y-%m-%d %H:%M:%S.%f")
                        #     query_to_filter.update({map_json[each_filter]: {"$gte": start_date, "$lte": end_date}})
        except Exception as e:
            logger.exception(f" while framing filter query {e}")
        return query_to_filter

    def get_tag_mapping(self):
        """
        Map tag id and tag names
        :return:
        """
        tag_mapping = {}
        tag_mapping_for_tag_header = {}
        try:
            # Map of tag names and tag id's
            try:
                for each_tag in self.mongo_obj.search_record_by_query(Dbm.mongo_db_name, Dbm.tags, {}):
                    tag_mapping[each_tag["tag_name"]] = each_tag["id"]
                    tag_mapping_for_tag_header[each_tag["id"]] = each_tag["tag_name"]
            except Exception as e:
                logger.exception(str(e))
        except Exception as e:
            logger.error(f"Error occurred while fetching tag mapping : {str(e)}")
        return tag_mapping, tag_mapping_for_tag_header

    def get_start_date_and_end_date(self, input_data):
        try:
            if input_data["time_range"]["filter_by"] == "interval" and input_data["time_range"]["interval"] in \
                    app_constants.AlarmTimeMapping.allowed_input_data_type:
                start_date, end_date = self.alarm_time_util.parse_relative_time_data(input_data["time_range"][
                                                                                         "interval"])
            elif input_data["time_range"]["filter_by"] == "range":
                start_date = datetime.strptime(input_data["time_range"]["range"]["from"] + ".000000",
                                               "%d-%m-%Y %H:%M:%S.%f")
                end_date = datetime.strptime(input_data["time_range"]["range"]["to"] + ".000000",
                                             "%d-%m-%Y %H:%M:%S.%f")
            else:
                raise Exception("Invalid Time Range Filters")
            return start_date, end_date
        except Exception as e:
            logger.error(f"Error occurred while fetching start date and end date for alarm filters : {str(e)}")
            raise Exception(str(e))

    def get_alarm_priority_list(self):
        alarm_dict = dict()
        try:
            logger.info("Get alarm priority list")
            for each_alarm in self.mongo_obj.fetch_all(Dbm.mongo_db_name, Dbm.alarm_priority):
                alarm_dict[each_alarm["id"]] = {"name": each_alarm["name"], "colour": each_alarm["priorityColor"]}
        except Exception as e:
            logger.error(f"Error occurred while fetching alarm priority list : {str(e)}")
            raise Exception("Failed to fetch alarm priority list")
        return alarm_dict

    def get_alarm_json(self, each_triggered_alarm, alarm_dict):
        try:
            alarm_name = ""
            priority_color = ''
            if each_triggered_alarm["priority"] in alarm_dict:
                alarm_name = alarm_dict[each_triggered_alarm["priority"]]["name"]
                priority_color = alarm_dict[each_triggered_alarm["priority"]]["colour"]
            tag_mapping = dict()
            try:
                for i in self.mongo_obj.search_record_by_query(Dbm.mongo_db_name, Dbm.tags, {}):
                    tag_mapping[i["id"]] = i["tag_name"]
            except Exception as e:
                logger.exception(str(e))

            alarm_tag_list = []
            for i in each_triggered_alarm["alarm_tag_list"]:
                alarm_tag_list.append(i.split("$")[-1])
            each_triggered_alarm["alarm_tag_list"] = alarm_tag_list
            tag_id_list = each_triggered_alarm["tag_id_list"]
            a = []
            for i in each_triggered_alarm["tag_id_list"]:
                a.append(i.split("$")[-1])
            each_triggered_alarm["tag_id_list"] = a
            alert_list = str(each_triggered_alarm["alarm_condition"]).split(",")
            new_alert_list = ""
            new_alert_list = new_alert_list[:-1]
            tag_name = []
            tag_id = []
            if "tag_id_list" in each_triggered_alarm:
                tag_id = each_triggered_alarm["tag_id_list"]
            else:
                tag_id.append(each_triggered_alarm["tag_id"].split("$")[-1])
            for each_id in tag_id:
                tag_name.append(tag_mapping[each_id])
            tag_id = tag_id_list
            if "." in each_triggered_alarm["start_time"]:
                each_triggered_alarm["start_time"] = each_triggered_alarm["start_time"].split(".")[0]
            device_names = ""
            devices = ""
            de_id_list = each_triggered_alarm["device_instance_id"][:-1].split(",")
            for each_dev in de_id_list:
                each_dev = each_dev.split("$tag")[0]
                devices = devices + each_dev + ","
                if each_dev in self.dev_cache:
                    device_names = device_names + str(self.dev_cache[each_dev]) + ","
                else:
                    name = self.get_component_name(each_dev)
                    device_names = device_names + name + ","
                    self.dev_cache[each_dev] = name
            for each_item in alert_list:
                try:
                    sp_data = each_item.split("$tag")[0]
                    for each_tag in alarm_tag_list:
                        if each_tag in each_item:
                            each_item = each_item.replace(each_tag, tag_mapping[each_tag])
                            if sp_data in self.dev_cache:
                                each_item = each_item.replace(sp_data, self.dev_cache[sp_data])
                            else:
                                name = self.get_component_name(sp_data)
                                each_item = each_item.replace(sp_data, name)
                    if each_item != "":
                        each_item = each_item.replace("$", ":")
                        new_alert_list += each_item + ","
                except Exception as e:
                    logger.exception("Exception occurred while iterating alert list conditions " + str(e))
            temp_json = {
                "alarm_event_id": each_triggered_alarm["id"],
                "alarmId": each_triggered_alarm["alarm_id"],
                "associateTo": "",
                "devices": devices[:-1],
                "deviceNames": device_names[:-1],
                "level": each_triggered_alarm["current_level"],
                "priority": alarm_name,
                "color": priority_color,
                "template": each_triggered_alarm["template"],
                "acknowledge": each_triggered_alarm["acknowledge"],
                "timeStamp": each_triggered_alarm["start_time"],
                "flag": "true",
                "via": "",
                "alarmName": each_triggered_alarm["alarmName"],
                "alarmType": each_triggered_alarm["alarmType"],
                "tag_id": tag_id,
                "alert_condition": new_alert_list,
                "tag_name": ",".join(tag_name)
            }
            return temp_json
        except Exception as e:
            logger.exception("Exception occurred while getting alarm json " + str(e))

    def get_alarm_json_updated(self, each_triggered_alarm, alarm_dict):
        try:
            mapping_json = {
                "Low": {"color": "#f1c21b", "alert_icon": "fa fa-exclamation-triangle text-warning fs-1"},
                "Critical": {"color": "#da1e28", "alert_icon": "fa fa-exclamation-triangle text-danger fs-1"},
                "Moderate": {"color": "#ff832b", "alert_icon": "fa fa-exclamation-triangle text-alert fs-1"}
            }
            alarm_name = ""
            priority_color = ''
            if each_triggered_alarm["priority"] in alarm_dict:
                alarm_name = alarm_dict[each_triggered_alarm["priority"]]["name"]
                priority_color = alarm_dict[each_triggered_alarm["priority"]]["colour"]
            tag_mapping = dict()
            try:
                for i in self.mongo_obj.search_record_by_query(Dbm.mongo_db_name, Dbm.tags, {}):
                    tag_mapping[i["id"]] = i["tag_name"]

            except Exception as e:
                logger.exception(str(e))

            alarm_tag_list = []
            for i in each_triggered_alarm["alarm_tag_list"]:
                alarm_tag_list.append(i.split("$")[-1])
            each_triggered_alarm["alarm_tag_list"] = alarm_tag_list
            tag_id_list = each_triggered_alarm["tag_id_list"]
            a = []
            for i in each_triggered_alarm["tag_id_list"]:
                a.append(i.split("$")[-1])
            each_triggered_alarm["tag_id_list"] = a
            alert_list = str(each_triggered_alarm["alarm_condition"]).split(",")
            new_alert_list = ""
            new_alert_list = new_alert_list[:-1]
            tag_name = []
            tag_id = []
            if "tag_id_list" in each_triggered_alarm:
                tag_id = each_triggered_alarm["tag_id_list"]
            else:
                tag_id.append(each_triggered_alarm["tag_id"].split("$")[-1])
            for each_id in tag_id:
                tag_name.append(tag_mapping[each_id])
            tag_id = tag_id_list
            if "." in each_triggered_alarm["start_time"]:
                each_triggered_alarm["start_time"] = each_triggered_alarm["start_time"].split(".")[0]
            device_names = ""
            devices = ""
            de_id_list = each_triggered_alarm["device_instance_id"][:-1].split(",")
            for each_dev in de_id_list:
                each_dev = each_dev.split("$tag")[0]
                devices = devices + each_dev + ","
                if each_dev in self.dev_cache:
                    device_names = device_names + str(self.dev_cache[each_dev]) + ","
                else:
                    name = self.get_component_name(each_dev)
                    device_names = device_names + name + ","
                    self.dev_cache[each_dev] = name
            for each_item in alert_list:
                try:
                    sp_data = each_item.split("$tag")[0]
                    for each_tag in alarm_tag_list:
                        if each_tag in each_item:
                            each_item = each_item.replace(each_tag, tag_mapping[each_tag])
                            if sp_data in self.dev_cache:
                                each_item = each_item.replace(sp_data, self.dev_cache[sp_data])
                            else:
                                name = self.get_component_name(sp_data)
                                each_item = each_item.replace(sp_data, name)
                    if each_item != "":
                        each_item = each_item.replace("$", ":")
                        new_alert_list += each_item + ","
                except Exception as e:
                    logger.exception("Exception occurred while iterating alert list conditions " + str(e))
            if "." in each_triggered_alarm["start_time"]:
                start_time = datetime.strptime(
                    each_triggered_alarm["start_time"], "%Y-%m-%d %H:%M:%S.%f").strftime("%d %b %Y, %H:%M")
            else:
                start_time = datetime.strptime(
                    each_triggered_alarm["start_time"], "%Y-%m-%d %H:%M:%S").strftime("%d %b %Y, %H:%M")
            new_alert_list = new_alert_list.split(":")[-1]
            temp_json = {
                "disabledActions": [],
                "alarm_acknowledged_icon": "",
                "alarm_event_id": each_triggered_alarm["id"],
                "alarmId": each_triggered_alarm["alarm_id"],
                "associateTo": "",
                "devices": devices[:-1],
                "deviceNames": device_names[:-1],
                "level": each_triggered_alarm["current_level"],
                "priority": alarm_name,
                "color": priority_color,
                "template": each_triggered_alarm["template"],
                "alarm_event_selected": each_triggered_alarm["acknowledge"],
                "acknowledge": each_triggered_alarm["acknowledge"],
                "timeStamp": start_time,
                "flag": "true",
                "via": "",
                "alarmName": each_triggered_alarm["alarmName"],
                "alarmType": each_triggered_alarm["alarmType"],
                "tag_id": tag_id,
                "alert_condition": new_alert_list,
                "tag_name": ",".join(tag_name),
                "alert_info": alarm_name,
                "iconStyle": {
                    "color": mapping_json[alarm_name]["color"]
                },
                "alert_icon": mapping_json[alarm_name]["alert_icon"]
            }
            if temp_json["acknowledge"]:
                temp_json["disabledActions"] = ["alarm_event_selected"]
                temp_json["alarm_acknowledged_icon"] = "fa fa-check-circle text-success fs-1"
            return temp_json, new_alert_list
        except Exception as e:
            logger.exception("Exception occurred while getting alarm json " + str(e))

    def get_tag_name(self, tag_id):
        try:
            tag_details = self.mongo_obj.find_one_with_condition(json_data={"id": tag_id}, collection_name=Dbm.tags,
                                                                 database_name=Dbm.mongo_db_name)
            if tag_details is not None:
                tag_name = tag_details["tag_name"]
                return tag_name
            else:
                logger.debug(
                    "Tag name not found for {}".format(tag_id), exc_info=True)
                return tag_id
        except Exception as e:
            logger.error("Tag name could not be found {}".format(str(e)), exc_info=True)
            return tag_id

    @staticmethod
    def get_user_alarm_flag(each_triggered_alarm, user_id):
        user_alarm_flag = False
        try:
            for each_trigger_levels in each_triggered_alarm["trigger_levels"]:
                for each_notify_profile in each_trigger_levels["notificaton_profile"]:
                    for each_user in each_notify_profile["usersOrUserGroup"]:
                        if each_user["value"] == user_id or each_triggered_alarm["created_by"] == user_id:
                            user_alarm_flag = True
                            break
                    if user_alarm_flag:
                        break
                if user_alarm_flag:
                    break
        except Exception as e:
            logger.exception("Exception occurred in get_user_alarm_flag " + str(e))
        return user_alarm_flag

    def get_notification_profile(self, each_triggered_alarm):
        via = ""
        try:
            notification_type_data = self.mongo_obj.find_one(db_name=Dbm.mongo_db_name, collection_name=Dbm.constants,
                                                             query={"content_type": "alarm_notify_type"},
                                                             search_json={"_id": 0, "data": 1})
            for each_trigger_level in each_triggered_alarm["trigger_levels"]:
                for each_notification_profile in each_trigger_level["notificaton_profile"]:
                    for sub_notification_profile in each_notification_profile["notificationProfile"]:
                        for each_notify_type in notification_type_data["data"]:
                            if each_notify_type["id"] == sub_notification_profile:
                                via = via + each_notify_type["name"] + ", "
        except Exception as e:
            logger.exception("Exception Occurred while getting notification profile" + str(e))
        return via

    def alarm_condition_fetch(self, input_data):
        final_json = {"status": "failed",
                      "data": {"severity": input_data["priority"], "alertCondition": input_data["alert_condition"],
                               "alertCreatedOn": "", "alertStatistics": {"total": "", "last7Days": "", "last30Days": "",
                                                                         "last12Months": ""},
                               "tableData": {"headerContent": app_constants.AlarmTimeMapping.condition_table_content,
                                             "bodyContent": []}}}
        try:
            alert_priority = input_data["priority"]
            qry = {"tag_id_list": {"$in": input_data["tag_id"]}}
            if alert_priority != "all":
                _id = self.mongo_obj.find_one(Dbm.mongo_db_name, Dbm.alarm_priority, {"name": alert_priority})["id"]
                qry["priority"] = _id
            all_records = self.mongo_obj.search_record_by_query2(Dbm.ilens_events, Dbm.triggered_alarms, qry,
                                                                 {"_id": 0})
            total_count = len(all_records)
            if not all_records:
                return {"status": "Failed", "message": "No Data Available for the given input"}
            trigger_start_time = all_records[0]["start_time"]
            if "." in str(trigger_start_time):
                trigger_start_time = datetime.strptime(
                    str(trigger_start_time), "%Y-%m-%d %H:%M:%S.%f")
            else:
                trigger_start_time = datetime.strptime(
                    str(trigger_start_time), "%Y-%m-%d %H:%M:%S")
            time_list = {"last_seven_days": 0, "last_thirty_days": 0, "last_one_year": 0}
            for each_interval in time_list:
                try:
                    start_date, end_date = self.alarm_time_util.parse_relative_time_data(each_interval)
                    for each_triggered_alarm in all_records:
                        tag_name_json = {}
                        value_json = {}
                        if "condition_json" in each_triggered_alarm:
                            for each_key, value in each_triggered_alarm["condition_json"].items():
                                if "tag_" in each_key and value:
                                    split_data = re.split(r'(>|<|>=|<=|==|!=)', each_key)
                                    tag_name_json[split_data[0]] = self.get_tag_name(split_data[0])
                                    value_json[split_data[0]] = each_triggered_alarm["tag_value_json"][split_data[0]]
                                    logger.debug("Fixe made")
                        else:
                            if "tag_value_json" in each_triggered_alarm:
                                for each_tag in each_triggered_alarm["tag_value_json"]:
                                    tag_id = each_tag.split("$")[-1]
                                    # dev_id = each_tag.split("$tag")[0]
                                    tag_name = self.get_tag_name(tag_id)
                                    # if dev_id in self.dev_cache:
                                    #     dev_name = self.dev_cache[dev_id]
                                    # else:
                                    #     dev_name = self.get_component_name(dev_id)
                                    # each_tag_name = dev_name + ":" + tag_name

                                    tag_name_json[each_tag] = tag_name
                                value_json = each_triggered_alarm["tag_value_json"]
                            else:
                                tag_name_json[each_triggered_alarm["tag_id"]] = self.get_tag_name(
                                    each_triggered_alarm["tag_id"])
                                value_json[each_triggered_alarm["tag_id"]] = each_triggered_alarm["tag_value"]
                        temp_json = {}
                        if "." in str(each_triggered_alarm["start_time"]):
                            alarm_time = datetime.strptime(
                                str(each_triggered_alarm["start_time"]), "%Y-%m-%d %H:%M:%S.%f")
                        else:
                            alarm_time = datetime.strptime(
                                str(each_triggered_alarm["start_time"]), "%Y-%m-%d %H:%M:%S")
                        if start_date <= alarm_time <= end_date:
                            if trigger_start_time > alarm_time:
                                trigger_start_time = alarm_time
                            time_list[each_interval] += 1
                            temp_json["triggered"] = datetime.strftime(alarm_time, "%Y-%m-%d %H:%M:%S")
                            temp_json["value"] = value_json
                            temp_json["tag_name_json"] = tag_name_json
                            temp_json["ackNote"] = ""
                            qry = {"alarmId": each_triggered_alarm["alarm_id"],
                                   "alarm_event_id": each_triggered_alarm["id"]}
                            notes_rec = ConnectionObj.mongo_connection_obj. \
                                find_one(Dbm.mongo_db_name, Dbm.alarm_note, qry)
                            if notes_rec:
                                temp_json["ackNote"] = notes_rec["notes"][-1]["text"]
                            if temp_json not in final_json["data"]["tableData"]["bodyContent"]:
                                final_json["data"]["tableData"]["bodyContent"].append(temp_json)
                except Exception as e:
                    logger.exception("Exception occurred while iterating time list to get count " + str(e))
            final_json["data"]["alertCreatedOn"] = datetime.strftime(trigger_start_time, "%Y-%m-%d %H:%M:%S")
            final_json["data"]["alertStatistics"]["total"] = total_count
            for each_count in time_list:
                if each_count == "last_seven_days":
                    final_json["data"]["alertStatistics"]["last7Days"] = time_list[each_count]
                if each_count == "last_thirty_days":
                    final_json["data"]["alertStatistics"]["last30Days"] = time_list[each_count]
                if each_count == "last_one_year":
                    final_json["data"]["alertStatistics"]["last12Months"] = time_list[each_count]
            final_json["status"] = "success"
            return final_json
        except Exception as e:
            logger.exception(str(e))
            return {"status": "failed", "message": "Failed"}

    def acknowledge_alarm(self, input_json):
        try:
            logger.info("inside the acknowledge_alarm")
            flag = False
            user_name = self.utility.get_usr_name(input_json)
            acknowledged_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            if "events" in input_json and input_json["events"]:
                for input_data in input_json["events"]:
                    try:
                        if "alarm_event_id" in input_data and "timeStamp" in input_data and "level" in input_data:
                            # searchtime = input_data["timeStamp"].strftime("%Y-%m-%d %H:%M:%S") + ".*"
                            searchtime = datetime.strptime(input_data["timeStamp"], '%d %b %Y, %H:%M').strftime(
                                "%Y-%m-%d %H:%M:%S") + ".*"
                            query_json = {"id": input_data["alarm_event_id"], "start_time": {"$regex": searchtime,
                                                                                             "$options": 'i'},
                                          "current_level": input_data["level"]}
                            self.mongo_obj.update_many(
                                db_name=Dbm.ilens_events, collection_name=Dbm.triggered_alarms, query=query_json,
                                set_json={"acknowledge": True, "acknowledged_by": user_name,
                                          "acknowledged_at": acknowledged_time})
                            self.mongo_obj.update_one(
                                db_name=Dbm.ilens_events, collection_name=Dbm.alarms, query=query_json,
                                set_json={"acknowledge": True, "acknowledged_by": user_name,
                                          "acknowledged_at": acknowledged_time})
                            flag = True
                    except Exception as e:
                        logger.exception(str(e))

            if flag:
                return {"status": "success", "message": "alarm acknowledged successfully"}
            else:
                return {"status": "failed", "message": "alarm event id key is missing"}
        except Exception as e:
            logger.exception("Exception in the acknowledge_alarm definition" + str(e))
            return {"status": "failed"}

    def get_note(self, input_json):
        final_json = {"status": "failed", "data": {}}
        try:
            node_data = self.mongo_obj.find_one(Dbm.mongo_db_name, Dbm.alarm_note,
                                                {"alarmId": input_json["alarmId"],
                                                 "alarm_event_id": input_json["alarm_event_id"],
                                                 "level": input_json["level"], "start_time": input_json["time_stamp"]},
                                                {"_id": 0})
            if node_data:
                final_json["data"] = node_data
            final_json["status"] = "success"
        except Exception as e:
            logger.exception("Exception" + str(e))
        return final_json

    def save_note(self, input_json):
        final_json = {"status": "failed", "message": "failed to save data"}
        try:
            logger.info("saving")
            node_data = self.mongo_obj.find_one(
                db_name=Dbm.mongo_db_name, collection_name=Dbm.alarm_note,
                query={"alarmId": input_json["alarmId"], "alarm_event_id": input_json["alarm_event_id"],
                       "level": input_json["level"], "start_time": input_json["time_stamp"]}, search_json={"_id": 0})

            if not node_data:
                input_json["start_time"] = input_json["time_stamp"]
                self.mongo_obj.database_insertion(Dbm.mongo_db_name, Dbm.alarm_note, input_json)
            else:
                node_data["notes"].append(input_json["notes"][0])
                self.mongo_obj.data_base_update_by_query(
                    Dbm.mongo_db_name, Dbm.alarm_note,
                    {"alarmId": input_json["alarmId"], "alarm_event_id": input_json["alarm_event_id"],
                     "level": input_json["level"], "start_time": input_json["time_stamp"]}, node_data)
            final_json["status"] = "success"
            final_json["message"] = "data updated successfully"
        except Exception as e:
            logger.exception("Exception" + str(e))
        return final_json

    def get_component_name(self, each_dev):
        site_data = {}
        name = ""
        try:
            for split_data in each_dev.split("$"):
                if "site_" in split_data:
                    site_data = self.mongo_obj.find_one(Dbm.mongo_db_name, Dbm.site_conf,
                                                        {"site_id": split_data})
                    name = name + site_data["site_name"]
                if "dept_" in split_data:
                    for each_dept in site_data["dept"]:
                        if each_dept["dept_id"] == split_data:
                            name = name + ">" + each_dept["dept_name"]
                            break
                if "line_" in split_data:
                    for each_line in site_data["line"]:
                        if each_line["line_id"] == split_data:
                            name = name + ">" + each_line["line_name"]
                            break
                if "equipment_" in split_data:
                    for each_equip in site_data["equipment"]:
                        if each_equip["equipment_id"] == split_data:
                            name = name + ">" + each_equip["equipment_name"]
                            break
            return name
        except Exception as e:
            logger.exception("Exception while framing name :" + str(e))
            return name

    def alarm_count(self, input_data, user_id):
        return_json = {"status": "success", "data": [{}]}
        try:
            alarm_count = 0
            alarm_priority = ""
            alarm_id = ""
            alarm_configuration_id = ""
            alarm_level = ""
            try:
                if user_id:
                    alarm_count, alarm_priority, alarm_id, alarm_configuration_id, alarm_level = \
                        self.alarm_count_definer(user_id)
            except Exception as e:
                logger.exception("Exception in the alarm tone" + str(e))
            return_json["data"][0]["alarmCount"] = alarm_count
            return_json["data"][0]["alarmPriority"] = alarm_priority
            return_json["data"][0]["alaramId"] = alarm_id
            return_json["data"][0]["alarmConfigurationId"] = alarm_configuration_id
            return_json["data"][0]["alarm_level"] = alarm_level
        except Exception as e:
            logger.exception("Exception while framing name :" + str(e))
        return return_json

    def alarm_count_definer(self, user_id):
        alarm_count = 0
        alarm_priority = ""
        alarm_configuration_id = ""
        alarm_id = ""
        alarm_level = 0
        try:
            priority_list = []
            priority_dict = dict()
            alarm_tone_dict = dict()
            date_dict = dict()
            alarm_id_dict = dict()
            user_record = self.mongo_obj.find_one(db_name=Dbm.mongo_db_name,
                                                  collection_name=Dbm.user,
                                                  query={"user_id": user_id},
                                                  search_json={"_id": 0})
            for each_triggered_alarm in ConnectionObj.mongo_connection_obj.search_record_by_query(Dbm.ilens_events,
                                                                                                  Dbm.triggered_alarms,
                                                                                                  {}, {"_id": 0}):
                try:
                    alarm_tone_dict = {}
                    alarm_id_dict[each_triggered_alarm["id"]] = each_triggered_alarm["alarm_id"]
                    try:
                        for each_level in each_triggered_alarm["trigger_levels"][0]["notificaton_profile"]:
                            if each_level["isNotificationToneShow"]:
                                for each_user in each_level["usersOrUserGroup"]:
                                    if each_user["type"] == "access_group":
                                        if each_user["value"] in user_record["access_group_ids"]:
                                            alarm_tone_dict.update({each_triggered_alarm["id"]:
                                                                        {"tone": each_level["notificationTone"],
                                                                         "level": int(
                                                                             each_triggered_alarm["current_level"])}})
                                    elif each_user["value"] == user_id:
                                        alarm_tone_dict.update({each_triggered_alarm["id"]:
                                                                    {"tone": each_level["notificationTone"],
                                                                     "level": int(
                                                                         each_triggered_alarm["current_level"])}})

                    except Exception as e:
                        logger.exception(e)
                    try:
                        for each_level in each_triggered_alarm["trigger_levels"][0]["notificaton_profile"]:
                            for each_user in each_level["usersOrUserGroup"]:
                                if each_user["type"] == "access_group":
                                    if each_user["value"] in user_record["access_group_ids"]:
                                        if "acknowledge" in each_triggered_alarm and not each_triggered_alarm[
                                            "acknowledge"]:
                                            alarm_count += 1
                                            if "." in each_triggered_alarm["start_time"]:
                                                date_dict[each_triggered_alarm["id"]] = datetime.strptime(
                                                    str(each_triggered_alarm["start_time"]), "%Y-%m-%d %H:%M:%S.%f")
                                            else:
                                                date_dict[each_triggered_alarm["id"]] = datetime.strptime(
                                                    str(each_triggered_alarm["start_time"]), "%Y-%m-%d %H:%M:%S")
                                            data = ConnectionObj.mongo_connection_obj.find_one(Dbm.mongo_db_name,
                                                                                               Dbm.alarm_priority,
                                                                                               {"id":
                                                                                                    each_triggered_alarm[
                                                                                                        "priority"]})
                                            if data and "priorityType" in data:
                                                if data["priorityType"] not in priority_list:
                                                    priority_list.append(data["priorityType"])
                                                    priority_dict[data["priorityType"]] = []
                                                priority_dict[data["priorityType"]].append(each_triggered_alarm["id"])
                                            break
                                elif each_user["value"] == user_id:
                                    if "acknowledge" in each_triggered_alarm and not each_triggered_alarm[
                                        "acknowledge"]:
                                        alarm_count += 1
                                        if "." in each_triggered_alarm["start_time"]:
                                            date_dict[each_triggered_alarm["id"]] = datetime.strptime(
                                                str(each_triggered_alarm["start_time"]), "%Y-%m-%d %H:%M:%S.%f")
                                        else:
                                            date_dict[each_triggered_alarm["id"]] = datetime.strptime(
                                                str(each_triggered_alarm["start_time"]), "%Y-%m-%d %H:%M:%S")
                                        data = ConnectionObj.mongo_connection_obj.find_one(Dbm.mongo_db_name,
                                                                                           Dbm.alarm_priority,
                                                                                           {"id": each_triggered_alarm[
                                                                                               "priority"]})
                                        if data and "priorityType" in data:
                                            if data["priorityType"] not in priority_list:
                                                priority_list.append(data["priorityType"])
                                                priority_dict[data["priorityType"]] = []
                                            priority_dict[data["priorityType"]].append(each_triggered_alarm["id"])
                                        break
                            if alarm_count != 0:
                                break
                    except Exception as e:
                        logger.exception(e)
                except Exception as e:
                    logger.exception(e)
                    pass
            try:
                if priority_list:
                    priority_list.sort()
                    date_list = []
                    for each_p in priority_dict[priority_list[0]]:
                        date_list.append(date_dict[each_p])
                    date_list.sort(reverse=True)
                    for key, value in date_dict.items():
                        try:
                            if value == date_list[0]:
                                if key not in alarm_tone_dict:
                                    continue
                                alarm_priority = alarm_tone_dict[key]["tone"]
                                alarm_level = alarm_tone_dict[key]["level"]
                                alarm_id = key
                                alarm_configuration_id = alarm_id_dict[key]
                        except Exception as e:
                            logger.exception(str(e))
                            pass
            except Exception as e:
                logger.exception(e)
        except Exception as e:
            logger.exception("Exception in the definition" + str(e))
        return alarm_count, alarm_priority, alarm_id, alarm_configuration_id, alarm_level

    def remove_removed_tags(self, previous_tags, selected_tags, alarm_id):
        try:
            removed_tags_from_rule = []
            conn_obj = self.alarm_redis
            for each_previous_tag in previous_tags:
                if each_previous_tag not in selected_tags:
                    removed_tags_from_rule.append(each_previous_tag)
            for each_tag in removed_tags_from_rule:
                conn_obj.hdel(each_tag, alarm_id)
            return True
        except Exception as e:
            logger.exception("Exception while removing tags from redis :" + str(e))
            return False
