# By: Riasat Ullah
# This file contains views for previewing status pages.

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 datetime
import json


@require_http_methods(['POST'])
def save_status_page_preview_session(request):
    '''
    Save the details necessary to prepare a status page for preview.
    :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())
            request.session[var_names.preview_page] = body
            return JsonResponse(lt.get_label(lnm.msg_success, lang), safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['GET'])
def status_page_preview(request):
    '''
    Get the current status page for preview along with the data.
    :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_status_pages, nav_bar_components
            )
            if not has_view_perm:
                raise exceptions.PermissionDenied

            full_path = request.get_full_path()
            if 'maintenance' in full_path:
                data_type = 'maintenance'
            elif 'past-incidents' in full_path:
                data_type = 'history'
            elif 'subscription/confirm' in full_path:
                data_type = 'subscribe'
            elif 'subscription/cancel' in full_path:
                data_type = 'unsubscribe'
            else:
                data_type = 'status'

            context = itsm_context.get_status_pages_preview_context(lang)

            if 'page' in request.GET:
                page_ref_id = request.GET.get('page')
                body = {var_names.page_ref_id: page_ref_id,
                        var_names.with_posts: True if data_type == 'status' else False}
                if settings.TEST_MODE:
                    if page_ref_id is None:
                        return JsonResponse(lt.get_label(lnm.err_unknown_resource, lang), status=400, safe=False)

                    status = 200
                    output = test_data_status_dashboard.status_page_preview_status[page_ref_id]
                else:
                    status, output = helpers.post_api_request(api_paths.status_pages_preview, body, request, lang=lang)

                if var_names.preview_page in request.session:
                    if status == 200:
                        stored_data = request.session[var_names.preview_page]
                        if page_ref_id is not None and stored_data[var_names.page_ref_id] != page_ref_id:
                            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)

                        bus_services = output[var_names.business_services]
                        posts = output[var_names.posts]

                        output = stored_data
                        output[var_names.business_services] = bus_services
                        output[var_names.posts] = posts

                    del request.session[var_names.preview_page]

                if status == 200:
                    context[var_names.context] = json.dumps({
                        var_names.page_ref_id: page_ref_id,
                        var_names.data_type: data_type,
                        var_names.redirect_base: '/itsm/external-status-pages/preview',
                        var_names.context: json.dumps(output, default=helpers.jsonify_unserializable)
                    })
            else:
                context = itsm_context.get_itsm_login_context(lang)
                return render(request, pages.external_sso_login_page, context=context)
            return render(request, pages.status_pages_preview_page, context=context)
        else:
            helpers.set_session_redirect_page(request)
            return redirect(pages.login_url)


@require_http_methods(['POST'])
def status_page_published_posts(request):
    '''
    Gets a list of published posts.
    :param request: Http request
    :return: JSON response
    '''
    lang = request_validator.get_user_language(request)
    if request_validator.user_in_session(request):
        body = json.loads(request.body.decode())
        page_ref_id = body[var_names.page_ref_id]
        is_maintenance = body[var_names.is_maintenance]
        start_period = datetime.datetime.strptime(body[var_names.start_period],
                                                  static_vars.json_timestamp_milli_format_with_tz)
        if settings.TEST_MODE:
            output = []
            if start_period <= datetime.datetime.now():
                if is_maintenance:
                    if page_ref_id in test_data_status_dashboard.status_page_preview_maintenances:
                        output = test_data_status_dashboard.status_page_preview_maintenances[
                            page_ref_id][var_names.posts]
                else:
                    if page_ref_id in test_data_status_dashboard.status_page_preview_past_incidents:
                        output = test_data_status_dashboard.status_page_preview_past_incidents[
                            page_ref_id][var_names.posts]
            return JsonResponse(output, safe=False)
        else:
            status, output = helpers.post_api_request(api_paths.status_pages_preview_posts, 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_preview_add_subscriber(request):
    '''
    Subscribe for notifications.
    :param request: Http request
    :return: JSON response
    '''
    lang = request_validator.get_user_language(request)
    if request_validator.user_in_session(request):
        json.loads(request.body.decode())
        return JsonResponse(lt.get_label(lnm.msg_status_page_subscriber_added, lang), status=200, safe=False)
    else:
        return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['POST'])
def status_page_preview_confirm_subscriber(request):
    '''
    Confirm a subscriber.
    :param request: Http request
    :return: JSON response
    '''
    lang = request_validator.get_user_language(request)
    if request_validator.user_in_session(request):
        body = json.loads(request.body.decode())
        if settings.TEST_MODE:
            page_ref_id = body[var_names.page_ref_id]
            status, output = 200, test_data_status_dashboard.status_page_subscribers[page_ref_id][-1]
        else:
            status, output = 400, 'Error'
        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_preview_cancel_subscriber(request):
    '''
    Cancel a subscriber.
    :param request: Http request
    :return: JSON response
    '''
    lang = request_validator.get_user_language(request)
    if request_validator.user_in_session(request):
        body = json.loads(request.body.decode())
        if settings.TEST_MODE:
            page_ref_id = body[var_names.page_ref_id]
            status, output = 200, test_data_status_dashboard.status_page_subscribers[page_ref_id][-1]
        else:
            status, output = 400, 'Error'
        return JsonResponse(output, status=status, safe=False)
    else:
        return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)
