# By: Riasat Ullah
# This file serves alert related pages and data.

from constants import api_paths, component_names as cnm, label_names as lnm, pages, static_vars, var_names
from context_manager import incidents_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_incidents
from translators import label_translator as lt
from utils import helpers, logging
from validations import request_validator
import json


@require_http_methods(['GET', 'POST'])
def get_all_task_alerts(request):
    '''
    Gets the list of all the task alerts that were received in the organization.
    :param request: Http request
    :return: Http 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, has_edit_perm = request_validator.get_session_permission(
                request, cnm.dis_com_alerts, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = incidents_context.get_alerts_list_context(lang, nav_bar_components)
            context[var_names.has_team_permission] = request_validator.get_team_permission_status(request)
            return render(request, pages.alerts_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:
                output = test_data_incidents.task_alerts
                if var_names.row_limit in body and var_names.row_offset in body:
                    row_limit = body[var_names.row_limit]
                    row_offset = body[var_names.row_offset]
                    if row_limit <= len(test_data_incidents.task_alerts):
                        start_ = row_offset
                        end_ = row_offset + row_limit
                        output = test_data_incidents.task_alerts[start_:end_]
                return JsonResponse(output, safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.incidents_alerts, body, request, lang=lang)
                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_pre_scheduled_alerts(request):
    '''
    GET: Gets the manual alerts page.
    POST: Gets the data for the page.
    :param request: Http request
    :return: GET -> Http response | 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, has_edit_perm = request_validator.get_session_permission(
                request, cnm.dis_com_incidents, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = incidents_context.get_pre_scheduled_alerts_context(lang, nav_bar_components)
            context[var_names.has_edit_permission] = has_edit_perm
            context[var_names.has_incident_create_permission] =\
                True if cnm.feat_incidents_create in request_validator.get_component_features(request) else False
            return render(request, pages.pre_scheduled_alert_list_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):
            if settings.TEST_MODE:
                return JsonResponse(test_data_incidents.pre_scheduled_alerts, safe=False)
            else:
                body = dict()
                status, output = helpers.post_api_request(api_paths.incidents_pre_scheduled_list,
                                                          body, request, lang=lang)
                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_pre_scheduled_alert_details(request, task_ref_id=None):
    '''
    Creates a manual alert.
    :param request: Http request
    :param task_ref_id: reference ID of the task whose details should be fetched.
    :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, has_edit_perm = request_validator.get_session_permission(
                request, cnm.dis_com_incidents, nav_bar_components
            )
            if not has_edit_perm:
                raise exceptions.PermissionDenied

            context = incidents_context.get_pre_scheduled_alert_details_context(lang, nav_bar_components)
            context[var_names.context] = json.dumps({var_names.task_ref_id: task_ref_id})
            context[var_names.is_new] = True if task_ref_id is None else False
            return render(request, pages.pre_scheduled_alert_details_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):
            if settings.TEST_MODE:
                for item in test_data_incidents.pre_scheduled_alerts:
                    if item[var_names.task_ref_id] == task_ref_id:
                        return JsonResponse(item, safe=False)
                return JsonResponse(lt.get_label(lnm.err_unknown_resource, lang), status=404, safe=False)
            else:
                try:
                    body = {var_names.task_ref_id: task_ref_id}
                    status, output = helpers.post_api_request(api_paths.incidents_pre_scheduled_details,
                                                              body, request, lang=lang)
                    return JsonResponse(output, status=status, safe=False)
                except Exception as e:
                    logging.exception(str(e))
                    return JsonResponse(lt.get_label(lnm.err_system_error, lang), status=500, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['POST'])
def create_pre_scheduled_alert(request):
    '''
    Edits a manual alert.
    :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())
            body[var_names.access_method] = static_vars.web

            if settings.TEST_MODE:
                return JsonResponse('Alert has been created', safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.incidents_pre_scheduled_create, body,
                                                          request, lang=lang)
                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 edit_pre_scheduled_alert(request):
    '''
    Edits a manual alert.
    :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('Alert has been edited', safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.incidents_pre_scheduled_edit, body, request,
                                                          lang=lang)
                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 delete_pre_scheduled_alert(request):
    '''
    Deletes a manual alert.
    :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('Alert has been deleted', safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.incidents_pre_scheduled_delete, body, request,
                                                          lang=lang)
                return JsonResponse(output, status=status, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)
