# By: Riasat Ullah
# This file contains functions for the analytics data.

from constants import api_paths, component_names as cnm, label_names as lnm, pages, static_vars, var_names
from context_manager import analytics_context
from django.core import exceptions
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.views.decorators.http import require_http_methods
from taskcallweb import settings
from system_tests.test_data import test_data_analytics, test_data_policies
from translators import label_translator as lt
from utils import helpers
from validations import request_validator
import datetime
import json


@require_http_methods(['POST'])
def get_dashboard(request):
    '''
    POST: Gets the set of data needed for the opening dashboard.
    :param request: Http request
    :return: GET: Http response; POST: JSON response
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            if settings.TEST_MODE:
                return JsonResponse(test_data_policies.dashboard_package, safe=False)
            else:
                body = dict()
                status, output = helpers.post_api_request(api_paths.dashboard_analytics, body, request)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET', 'POST'])
def get_aggregate_notifications(request):
    '''
    GET: Gets the aggregate notifications report page.
    POST: Gets the aggregate notifications data.
    :param request: Http request
    :return: GET: Http response  |  POST: JSON response
    '''
    if request.method == 'GET':
        if request_validator.user_in_session(request):
            lang = request_validator.get_user_language(request)
            nav_bar_components = request_validator.get_nav_bar_components(request)

            has_view_perm = request_validator.has_view_permission(
                request, cnm.dis_com_notification_analytics, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = analytics_context.get_aggregate_notifications_context(lang, nav_bar_components)
            return render(request, pages.notifications_aggregate_analytics_page, context=context)
        else:
            helpers.set_session_redirect_page(request)
            return redirect(pages.login_url)
    elif request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            body = json.loads(request.body.decode())
            if settings.TEST_MODE:
                return JsonResponse(test_data_analytics.aggregate_alert_report, safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.notifications_aggregate, body, request)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET', 'POST'])
def get_day_notifications(request, alert_date):
    '''
    GET: Gets the day notifications report page.
    POST: Gets the day notifications report data.
    :param request: Http request
    :param alert_date: the date to get the alert data for
    :return: GET: Http response  |  POST: JSON response
    '''
    if request.method == 'GET':
        if request_validator.user_in_session(request):
            try:
                # check if the date is a real date or not
                datetime.datetime.strptime(alert_date, static_vars.date_format)

                lang = request_validator.get_user_language(request)
                nav_bar_components = request_validator.get_nav_bar_components(request)

                has_view_perm = request_validator.has_view_permission(
                    request, cnm.dis_com_notification_analytics, nav_bar_components
                )
                if not has_view_perm:
                    raise exceptions.PermissionDenied

                context = analytics_context.get_day_notifications_context(lang, nav_bar_components)
                context[var_names.context] = json.dumps({var_names.notification_date: alert_date})
                return render(request, pages.notifications_day_analytics_page, context=context)
            except (TypeError, ValueError):
                return redirect(pages.error_page)
        else:
            helpers.set_session_redirect_page(request)
            return redirect(pages.login_url)
    elif request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            try:
                body = {var_names.notification_date: alert_date}
                if settings.TEST_MODE:
                    return JsonResponse(test_data_analytics.day_alert_report, safe=False)
                else:
                    status, output = helpers.post_api_request(api_paths.notifications_day, body, request)
                    return JsonResponse(output, status=status, safe=False)
            except (TypeError, ValueError):
                return JsonResponse(lt.get_label(lnm.err_invalid_request, lang), status=400, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET', 'POST'])
def get_incident_analytics(request):
    '''
    On GET: Gets the standard incident analytics page.
    On POST: Gets standard incident analytics data.
    :param request: Http request
    :return: JSON response
    '''
    if request.method == 'GET':
        if request_validator.user_in_session(request):
            lang = request_validator.get_user_language(request)
            nav_bar_components = request_validator.get_nav_bar_components(request)
            component_features = request_validator.get_component_features(request)

            has_view_perm = request_validator.has_view_permission(
                request, cnm.dis_com_incident_analytics, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = analytics_context.get_incident_analytics_context(lang, nav_bar_components)
            context[var_names.has_analytics_secondary_permission] =\
                True if cnm.feat_analytics_secondary in component_features else False
            context[var_names.has_contextual_search_permission] = request_validator.has_view_permission(
                request, cnm.dis_com_tags)
            return render(request, pages.incident_analytics_page, context=context)
        else:
            helpers.set_session_redirect_page(request)
            return redirect(pages.login_url)
    elif request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            body = json.loads(request.body.decode())

            if settings.TEST_MODE:
                return JsonResponse(test_data_analytics.incident_standard_analytics, safe=False)
            else:
                ip_address = request.META.get(static_vars.ip_address_attribute)
                timezone = helpers.get_info_from_ip_address(ip_address, static_vars.ip_timezone_attribute)
                body[var_names.timezone] = timezone

                status, output = helpers.post_api_request(api_paths.incident_analytics, body, request)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET'])
def user_analytics_page(request):
    '''
    On GET: Gets the user analytics page.
    :param request: Http request
    :return: JSON response
    '''
    if request.method == 'GET':
        if request_validator.user_in_session(request):
            lang = request_validator.get_user_language(request)
            nav_bar_components = request_validator.get_nav_bar_components(request)

            has_view_perm = request_validator.has_view_permission(
                request, cnm.dis_com_user_analytics, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = analytics_context.get_user_analytics_context(lang, nav_bar_components)
            context[var_names.has_contextual_search_permission] = request_validator.has_view_permission(
                request, cnm.dis_com_tags)
            return render(request, pages.user_analytics_page, context=context)
        else:
            helpers.set_session_redirect_page(request)
            return redirect(pages.login_url)


@require_http_methods(['POST'])
def get_user_summary_analytics(request):
    '''
    Gets the summary analytics data of users of an organization.
    :param request: Http request
    :return: JSON response
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            body = json.loads(request.body.decode())

            if settings.TEST_MODE:
                return JsonResponse(test_data_analytics.user_summary, safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.user_summary_analytics, body, request)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['POST'])
def get_user_individual_analytics(request):
    '''
    Gets the individual analytics data of a specific user.
    :param request: Http request
    :return: JSON response
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            body = json.loads(request.body.decode())
            if settings.TEST_MODE:
                return JsonResponse(test_data_analytics.user_individual, safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.user_individual_analytics, body, request)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET', 'POST'])
def get_team_analytics(request):
    '''
    Get team analytics.
    :param request: Http request
    :return: GET: HttpResponse  |  POST: JsonResponse
    '''
    if request.method == 'GET':
        if request_validator.user_in_session(request):
            lang = request_validator.get_user_language(request)
            nav_bar_components = request_validator.get_nav_bar_components(request)

            has_view_perm = request_validator.has_view_permission(
                request, cnm.dis_com_team_analytics, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = analytics_context.get_team_analytics_context(lang, nav_bar_components)
            context[var_names.has_contextual_search_permission] = request_validator.has_view_permission(
                request, cnm.dis_com_tags)
            return render(request, pages.team_analytics_page, context=context)
        else:
            helpers.set_session_redirect_page(request)
            return redirect(pages.login_url)
    elif request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            body = json.loads(request.body.decode())

            if settings.TEST_MODE:
                return JsonResponse(test_data_analytics.team_analytics, safe=False)
            else:
                ip_address = request.META.get(static_vars.ip_address_attribute)
                timezone = helpers.get_info_from_ip_address(ip_address, static_vars.ip_timezone_attribute)
                body[var_names.timezone] = timezone

                status, output = helpers.post_api_request(api_paths.team_analytics, body, request)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET', 'POST'])
def get_service_analytics(request):
    '''
    Get service analytics.
    :param request: Http request
    :return: GET: HttpResponse  |  POST: JsonResponse
    '''
    if request.method == 'GET':
        if request_validator.user_in_session(request):
            lang = request_validator.get_user_language(request)
            nav_bar_components = request_validator.get_nav_bar_components(request)

            has_view_perm = request_validator.has_view_permission(
                request, cnm.dis_com_service_analytics, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = analytics_context.get_service_analytics_context(lang, nav_bar_components)
            context[var_names.has_contextual_search_permission] = request_validator.has_view_permission(
                request, cnm.dis_com_tags)
            return render(request, pages.service_analytics_page, context=context)
        else:
            helpers.set_session_redirect_page(request)
            return redirect(pages.login_url)
    elif request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            body = json.loads(request.body.decode())

            if settings.TEST_MODE:
                return JsonResponse(test_data_analytics.service_analytics, safe=False)
            else:
                ip_address = request.META.get(static_vars.ip_address_attribute)
                timezone = helpers.get_info_from_ip_address(ip_address, static_vars.ip_timezone_attribute)
                body[var_names.timezone] = timezone

                status, output = helpers.post_api_request(api_paths.service_analytics, body, request)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET', 'POST'])
def get_business_impact_analytics(request):
    '''
    Get business impact analytics.
    :param request: HttpRequest
    :return: GET: HttpResponse  |  POST: JsonResponse
    '''
    if request.method == 'GET':
        if request_validator.user_in_session(request):
            lang = request_validator.get_user_language(request)
            nav_bar_components = request_validator.get_nav_bar_components(request)

            has_view_perm = request_validator.has_view_permission(
                request, cnm.dis_com_business_impact_analytics, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = analytics_context.get_business_impact_analytics_context(lang, nav_bar_components)
            context[var_names.has_contextual_search_permission] = request_validator.has_view_permission(
                request, cnm.dis_com_tags)
            return render(request, pages.business_impact_analytics_page, context=context)
        else:
            helpers.set_session_redirect_page(request)
            return redirect(pages.login_url)
    elif request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            body = json.loads(request.body.decode())

            if settings.TEST_MODE:
                return JsonResponse(test_data_analytics.business_impact_analytics, safe=False)
            else:
                ip_address = request.META.get(static_vars.ip_address_attribute)
                timezone = helpers.get_info_from_ip_address(ip_address, static_vars.ip_timezone_attribute)
                body[var_names.timezone] = timezone

                status, output = helpers.post_api_request(api_paths.business_impact_analytics, body, request)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET', 'POST'])
def get_live_call_analytics(request):
    '''
    Get the live call routing analytics.
    :param request: HttpRequest
    :return: GET: HttpResponse  |  POST: JsonResponse
    '''
    if request.method == 'GET':
        if request_validator.user_in_session(request):
            lang = request_validator.get_user_language(request)
            nav_bar_components = request_validator.get_nav_bar_components(request)
            component_features = request_validator.get_component_features(request)

            has_view_perm = request_validator.has_view_permission(
                request, cnm.dis_com_live_call_analytics, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = analytics_context.get_live_call_analytics_context(lang, nav_bar_components)
            context[var_names.has_analytics_secondary_permission] =\
                True if cnm.feat_analytics_secondary in component_features else False
            return render(request, pages.live_call_analytics_page, context=context)
        else:
            helpers.set_session_redirect_page(request)
            return redirect(pages.login_url)
    elif request.method == 'POST':
        lang = request_validator.get_user_language(request)
        if request_validator.user_in_session(request):
            body = json.loads(request.body.decode())

            if settings.TEST_MODE:
                return JsonResponse(test_data_analytics.live_call_analytics, safe=False)
            else:
                ip_address = request.META.get(static_vars.ip_address_attribute)
                timezone = helpers.get_info_from_ip_address(ip_address, static_vars.ip_timezone_attribute)
                body[var_names.timezone] = timezone

                status, output = helpers.post_api_request(api_paths.live_calls_analytics, body, request)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)
