# By: Riasat Ullah
# ServiceAnalytics is an object that allows service specific analytics to be prepared.

from analytics import analytics_tools
from analytics.instance_analyzer import InstanceAnalyzer
from dbqueries import db_analytics, db_services, db_teams
from utils import constants, var_names


class ServiceAnalytics(object):

    def __init__(self, conn, timestamp, organization_id, start_date, end_date, timezone,
                 service_refs=None, team_refs=None, tags=None, user_id=None):
        self.conn = conn
        self.timestamp = timestamp
        self.organization_id = organization_id
        self.start_date = start_date
        self.end_date = end_date
        self.timezone = timezone
        self.service_refs = service_refs
        self.team_refs = team_refs
        self.tags = tags
        self.user_id = user_id

        self.service_ids = None
        if service_refs is not None:
            self.service_ids = db_services.list_service_ids_from_ref_ids(conn, timestamp, organization_id, service_refs)

        if team_refs is not None:
            team_serv_ids = db_teams.list_team_service_ids_from_ref_ids(conn, timestamp, organization_id, team_refs)
            if len(team_serv_ids) > 0:
                if self.service_ids is None:
                    self.service_ids = team_serv_ids
                elif self.service_ids is not None and isinstance(self.service_ids, list) and len(self.service_ids) > 0:
                    self.service_ids = list(set(self.service_ids).intersection(set(team_serv_ids)))

        self.last_six_periods = analytics_tools.get_previous_periods(start_date, end_date, 6)
        self.instances = db_analytics.get_instances_for_analysis(conn, start_date, end_date, organization_id,
                                                                 service_ids=self.service_ids, tags=self.tags,
                                                                 user_id=self.user_id)

    def get_specific_urgency_metrics(self, urgency_level):
        '''
        Gets the analytical metrics for a specific urgency level.
        :param urgency_level: (int) urgency level
        :return: (dict) of details
        '''
        analyzer = InstanceAnalyzer(self.timezone, self.instances)
        analyzer.filter_by_urgency_level([urgency_level])

        daily_instance_count = db_analytics.get_daily_instance_count(
            self.conn, self.last_six_periods[0][0], self.last_six_periods[-1][1], self.organization_id,
            urgencies=[urgency_level], service_ids=self.service_ids
        )
        trend = analytics_tools.get_period_totals(self.last_six_periods, daily_instance_count)

        return {
            var_names.incident_count: analyzer.get_aggregate_instance_count(),
            var_names.response_time: analytics_tools.convert_nan_to_number(analyzer.get_aggregate_response_effort()),
            var_names.mean_resolution_time: analytics_tools.convert_nan_to_number(
                analyzer.get_average_response_effort()),
            var_names.longest_resolution_time: analytics_tools.convert_nan_to_number(
                analyzer.get_longest_response_effort()),
            var_names.trend: trend
        }

    def get_metrics(self):
        '''
        Get all the metrics needed for service analytics.
        :return: (dict of dict) -> metric details
        '''
        analyzer = InstanceAnalyzer(self.timezone, self.instances)

        return {
            var_names.critical_urgency_incidents: self.get_specific_urgency_metrics(constants.critical_urgency),
            var_names.high_urgency_incidents: self.get_specific_urgency_metrics(constants.high_urgency),
            var_names.longest_incidents: analyzer.get_longest_major_instances(count=5),
            var_names.loudest_services: analyzer.get_loudest_services_instance_count(count=5),
            var_names.business_impact: analyzer.get_most_business_impacting_services(count=5),
            var_names.longest_business_impact: analyzer.get_longest_impacted_business_services(count=5)
        }
