# By: Riasat Ullah
# This file contains status page post views.

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


####################
# Common
####################

@require_http_methods(['POST'])
def create_status_page_post(request, page_ref_id):
    '''
    Save a status page post. If pre-approval is required this post will be treated as a pending item. Otherwise,
    a new incident or status update will get created and published.
    :param request: Http request
    :param page_ref_id: reference ID of the status page whose incidents are being requested
    :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 body[var_names.page_ref_id] != page_ref_id:
                return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)

            if settings.TEST_MODE:
                return JsonResponse(lt.get_label(lnm.msg_success, lang), safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.status_pages_posts_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 delete_status_page_post(request, page_ref_id):
    '''
    Deletes a status page incident.
    :param request: Http request
    :param page_ref_id: reference ID of the status page whose incidents are being requested
    :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 body[var_names.page_ref_id] != page_ref_id:
                return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)
            if settings.TEST_MODE:
                return JsonResponse(lt.get_label(lnm.msg_status_page_incident_deleted, lang), safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.status_pages_posts_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)


@require_http_methods(['GET', 'POST'])
def list_status_page_posts(request, page_ref_id):
    '''
    GET: Returns the status pages post list html page.
    POST: Gets a list of posts for this status page given certain parameters.
    :param request: Http request
    :param page_ref_id: reference ID of the status page whose incidents are being requested
    :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, has_edit_perm = request_validator.get_session_permission(
                request, cnm.dis_com_status_pages, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = itsm_context.get_status_pages_incidents_context(lang, nav_bar_components)
            context[var_names.context] = json.dumps({var_names.page_ref_id: page_ref_id})
            context[var_names.has_edit_permission] = has_edit_perm

            if 'tab' in request.GET:
                context[var_names.tab_name] = request.GET.get('tab')

            return render(request, pages.status_pages_posts_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 body[var_names.page_ref_id] == page_ref_id:
                if settings.TEST_MODE:
                    is_maintenance = body[var_names.is_maintenance]
                    filter_state = body[var_names.status]
                    if is_maintenance:
                        if page_ref_id in test_data_status_dashboard.status_page_maintenances:
                            if filter_state == static_vars.completed_state:
                                output = [x for x in test_data_status_dashboard.status_page_maintenances[page_ref_id]
                                          if x[var_names.status] == static_vars.completed_state]
                            else:
                                output = [x for x in test_data_status_dashboard.status_page_maintenances[page_ref_id]
                                          if x[var_names.status] != static_vars.completed_state]
                            return JsonResponse(output, safe=False)
                        else:
                            return JsonResponse([], safe=False)
                    else:
                        if page_ref_id in test_data_status_dashboard.status_page_incidents:
                            if filter_state == static_vars.resolved_state:
                                output = [x for x in test_data_status_dashboard.status_page_incidents[page_ref_id]
                                          if x[var_names.status] == static_vars.resolved_state]
                            else:
                                output = [x for x in test_data_status_dashboard.status_page_incidents[page_ref_id]
                                          if x[var_names.status] != static_vars.resolved_state]
                            return JsonResponse(output, safe=False)
                        else:
                            return JsonResponse([], safe=False)
                else:
                    status, output = helpers.post_api_request(api_paths.status_pages_posts_list,
                                                              body, request, lang=lang)
                    return JsonResponse(output, status=status, safe=False)
            else:
                return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=403, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET', 'POST'])
def status_page_post_details(request, page_ref_id):
    '''
    GET: Returns the status pages post HTML page.
    POST: Gets the details of a status page post.
    :param request: Http request
    :param page_ref_id: reference ID of the status page
    :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, has_edit_perm = request_validator.get_session_permission(
                request, cnm.dis_com_status_pages, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            context = itsm_context.get_status_pages_post_details_context(lang, nav_bar_components)
            info_context = {var_names.page_ref_id: page_ref_id}

            logging.info(request.get_full_path())
            if 'maintenance' in request.get_full_path():
                info_context[var_names.is_maintenance] = True
            else:
                info_context[var_names.is_maintenance] = False

            if 'incident' in request.GET:
                info_context[var_names.page_post_id] = request.GET.get('incident')
            if 'maintenance' in request.GET:
                info_context[var_names.page_post_id] = request.GET.get('maintenance')
            if 'pending' in request.GET:
                info_context[var_names.pending] = request.GET.get('pending')
            context[var_names.context] = json.dumps(info_context)
            context[var_names.has_edit_permission] = has_edit_perm

            return render(request, pages.status_pages_post_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):
            body = json.loads(request.body.decode())
            if settings.TEST_MODE:
                all_posts = test_data_status_dashboard.status_page_incidents[page_ref_id] +\
                            test_data_status_dashboard.status_page_maintenances[page_ref_id]
                for item in all_posts:
                    if item[var_names.page_post_id] == body[var_names.page_post_id]:
                        return JsonResponse(item, safe=False)

                return JsonResponse(lt.get_label(lnm.err_unknown_resource, lang), status=404, safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.status_pages_posts_details,
                                                          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)


####################
# Incidents
####################

@require_http_methods(['POST'])
def status_page_sync_with_system_incident(request, page_ref_id):
    '''
    Sync a status page incident with a system incident.
    :param request: Http request
    :param page_ref_id: reference ID of the status page whose incidents are being requested
    :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_status_dashboard.status_page_pending[page_ref_id], safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.status_pages_posts_sync, 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)


#############################
# Pending
#############################

@require_http_methods(['POST'])
def status_page_pending_items(request, page_ref_id):
    '''
    Gets the status page items pending approval - new incidents, status updates, maintenance.
    :param request: Http request
    :param page_ref_id: reference ID of the status page whose incidents are being requested
    :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_status_dashboard.status_page_pending[page_ref_id], safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.status_pages_posts_pending_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(['POST'])
def status_page_pending_item_details(request, page_ref_id):
    '''
    Get the details of a pending item.
    :param request: Http request
    :param page_ref_id: reference ID of the status page
    :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:
                for item in test_data_status_dashboard.status_page_pending[page_ref_id]:
                    if item[var_names.event_ref_id] == body[var_names.event_ref_id]:
                        return JsonResponse(item, safe=False)
                return JsonResponse(lt.get_label(lnm.err_unknown_resource, lang), status=404, safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.status_pages_posts_pending_details,
                                                          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 approve_pending_item(request, page_ref_id):
    '''
    Approve a pending item.
    :param request: Http request
    :param page_ref_id: reference ID of the status page whose incidents are being requested
    :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 body[var_names.page_ref_id] != page_ref_id:
                return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)

            if settings.TEST_MODE:
                return JsonResponse('Pending items has been approved', safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.status_pages_posts_pending_approve,
                                                          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 reject_pending_item(request, page_ref_id):
    '''
    Reject a pending item.
    :param request: Http request
    :param page_ref_id: reference ID of the status page whose incidents are being requested
    :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 body[var_names.page_ref_id] != page_ref_id:
                return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)
            if settings.TEST_MODE:
                return JsonResponse('Pending items has been rejected', safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.status_pages_posts_pending_reject,
                                                          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)
