#import concurrent
import requests
from .internal_event_ops import InternalEventOperations
from models.event_notification import EventNotification
from models.access_control_policy_list_ext import AccessControlPolicyListExt
from models.capif_event_detail import CAPIFEventDetail
from models.event_subscription import EventSubscription
from models.service_api_description import ServiceAPIDescription
from encoder import CustomJSONEncoder
import sys
import json
from flask import current_app
import asyncio
import aiohttp
from util import dict_to_camel_case, clean_empty, serialize_clean_camel_case

class Notifications():

    def __init__(self):
        self.events_ops = InternalEventOperations()

    def send_notifications(self, redis_event):
        try:
            if redis_event.get('event', None) == None:
                raise("Event value is not present on received event from REDIS")
            
            current_app.logger.info("Received event " + redis_event.get('event') + ", sending notifications")
            subscriptions = self.events_ops.get_event_subscriptions(redis_event.get('event'))
            current_app.logger.info(subscriptions)

            for sub in subscriptions:
                url = sub["notification_destination"]
                current_app.logger.debug(url)
                data = EventNotification(sub["subscription_id"], events=redis_event.get('event'))
                if redis_event.get('key', None) != None and redis_event.get('information', None) != None:
                    if EventSubscription.return_supp_feat_dict(sub["supported_features"])["EnhancedEventReport"]:
                        event_detail={}
                        for pos, key in enumerate(redis_event.get('key', None)):
                            current_app.logger.debug(f"information: {redis_event.get('information', None)[pos]}")
                            if redis_event.get('event', None) in ["SERVICE_API_AVAILABLE", "SERVICE_API_UNAVAILABLE"] and key == "apiIds":
                                event_detail["apiIds"]=[redis_event.get('information', None)[pos]]
                            elif EventSubscription.return_supp_feat_dict(sub["supported_features"])["ApiStatusMonitoring"] and  key == "serviceAPIDescriptions":
                                event_detail["serviceAPIDescriptions"]=redis_event.get('information', None)[pos]
                            elif redis_event.get('event', None) in ["SERVICE_API_UPDATE"]:
                                event_detail["serviceAPIDescriptions"]=redis_event.get('information', None)[pos]
                            elif redis_event.get('event', None) in ["API_INVOKER_ONBOARDED", "API_INVOKER_OFFBOARDED", "API_INVOKER_UPDATED"]:
                                event_detail["apiInvokerIds"]=redis_event.get('information', None)[pos]
                            elif redis_event.get('event', None) in ["ACCESS_CONTROL_POLICY_UPDATE"]:
                                event_detail["accCtrlPolList"]=redis_event.get('information', None)[pos]
                            elif redis_event.get('event', None) in ["SERVICE_API_INVOCATION_SUCCESS", "SERVICE_API_INVOCATION_FAILURE"]:
                                event_detail["invocationLogs"]=redis_event.get('information', None)[pos]
                            elif redis_event.get('event', None) in ["API_TOPOLOGY_HIDING_CREATED", "API_TOPOLOGY_HIDING_REVOKED"]:
                                event_detail["apiTopoHide"]=redis_event.get('information', None)[pos]

                        current_app.logger.debug(event_detail)
                        data.event_detail=event_detail

                current_app.logger.debug(json.dumps(data.to_dict(),cls=CustomJSONEncoder))

                asyncio.run(self.send(url, serialize_clean_camel_case(data)))

        except Exception as e:
            current_app.logger.error("An exception occurred ::" + str(e))
            return False

    def request_post(self, url, data):
        headers = {'content-type': 'application/json'}
        return requests.post(url, json={'text': str(data.to_str())}, headers=headers)
    
    async def send_request(self, url, data):
        async with aiohttp.ClientSession() as session:
            timeout = aiohttp.ClientTimeout(total=10)  # Establecer timeout a 10 segundos
            headers = {'content-type': 'application/json'}
            async with session.post(url, json=data, timeout=timeout, headers=headers) as response:
                return await response.text()
    
    async def send(self, url, data):
        try:
            response = await self.send_request(url, data)
            current_app.logger.debug(response)
        except asyncio.TimeoutError:
            current_app.logger.error("Timeout: Request timeout")
        except Exception as e:
            current_app.logger.error("An exception occurred sending notification::" + str(e))
            return False
