# By: Riasat Ullah
# This file contains views for status page subscribers Add/Remove.

from data_syncers import syncer_status_pages
from dbqueries.status_pages import db_status_page_subscribers
from exceptions.user_exceptions import UnauthorizedRequest
from modules import status_page_notifier
from rest_framework.decorators import api_view
from rest_framework.response import Response
from translators import label_translator as _lt
from utils import errors, info, logging, permissions, times, tokenizer, var_names
from utils.db_connection import CONN_POOL
from validations import request_validator
import jwt


@api_view(['POST'])
def list_subscribers(request, conn=None):
    '''
    List the subscribers of a status page.
    :param request: Http request
    :param conn: db connection
    :return: JSON response -> list
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        expected_fields = [var_names.page_ref_id]
        optional_fields = [var_names.subscription_type, var_names.keywords, var_names.row_limit, var_names.row_offset]
        try:
            conn = CONN_POOL.get_db_conn() if conn is None else conn
            request_validator.validate_fields(request, expected_fields, optional_fields)
            user_id, org_id, user_perm, org_perm = tokenizer.authorize_request(request)

            sub_type = request.data[var_names.subscription_type]\
                if var_names.subscription_type in request.data else None
            keywords = request.data[var_names.keywords] if var_names.keywords in request.data else None
            row_limit = request.data[var_names.row_limit] if var_names.row_limit in request.data else None
            row_offset = request.data[var_names.row_offset] if var_names.row_offset in request.data else None

            if not permissions.has_org_permission(org_perm, permissions.ORG_STATUS_PAGES_PERMISSION):
                return Response(_lt.get_label(errors.err_subscription_rights, lang), status=403)
            if not permissions.has_user_permission(user_perm, permissions.USER_STATUS_PAGES_PERMISSION):
                return Response(_lt.get_label(errors.err_user_rights, lang), status=403)

            data_list = db_status_page_subscribers.list_status_page_subscribers(
                conn, times.get_current_timestamp(), org_id, request.data[var_names.page_ref_id],
                subscription_type=sub_type, keywords=keywords, row_limit=row_limit, row_offset=row_offset
            )
            return Response(data_list)
        except (UnauthorizedRequest, jwt.ExpiredSignatureError, jwt.InvalidSignatureError) as e:
            logging.exception(str(e))
            return Response(_lt.get_label(errors.err_authorization, lang), status=401)
        except Exception as e:
            logging.exception(str(e))
            return Response(_lt.get_label(errors.err_system_error, lang), status=500)
        finally:
            CONN_POOL.put_db_conn(conn)


@api_view(['POST'])
def add_subscribers(request, conn=None):
    '''
    Add subscribers to a status page.
    :param request: Http request
    :param conn: db connection
    :return: JSON response -> list
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        expected_fields = [var_names.page_ref_id, var_names.subscribers]
        page_ref_id, sub_ref_list = None, []
        try:
            conn = CONN_POOL.get_db_conn() if conn is None else conn
            request_validator.validate_fields(request, expected_fields)
            user_id, org_id, user_perm, org_perm = tokenizer.authorize_request(request)

            if not permissions.has_org_permission(org_perm, permissions.ORG_STATUS_PAGES_PERMISSION):
                return Response(_lt.get_label(errors.err_subscription_rights, lang), status=403)
            if not permissions.has_user_permission(user_perm, permissions.USER_STATUS_PAGES_PERMISSION):
                return Response(_lt.get_label(errors.err_user_rights, lang), status=403)

            page_ref_id = request.data[var_names.page_ref_id]
            subscribers = request.data[var_names.subscribers]

            sub_ref_list = db_status_page_subscribers.add_status_page_subscriber(
                conn, times.get_current_timestamp(), org_id, page_ref_id, subscribers
            )
            return Response(_lt.get_label(info.msg_status_page_subscriber_added, lang))
        except LookupError as e:
            logging.exception(str(e))
            return Response(_lt.get_label(str(e), lang), status=400)
        except (UnauthorizedRequest, jwt.ExpiredSignatureError, jwt.InvalidSignatureError) as e:
            logging.exception(str(e))
            return Response(_lt.get_label(errors.err_authorization, lang), status=401)
        except Exception as e:
            logging.exception(str(e))
            return Response(_lt.get_label(errors.err_system_error, lang), status=500)
        finally:
            syncer_status_pages.send_status_page_subscriber_confirmation_request(conn, page_ref_id, sub_ref_list)
            CONN_POOL.put_db_conn(conn)


@api_view(['POST'])
def delete_subscribers(request, conn=None):
    '''
    Delete a status page subscribers.
    :param request: Http request
    :param conn: db connection
    :return: JSON response -> list
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        expected_fields = [var_names.page_ref_id, var_names.subscribers]
        try:
            conn = CONN_POOL.get_db_conn() if conn is None else conn
            request_validator.validate_fields(request, expected_fields)
            user_id, org_id, user_perm, org_perm = tokenizer.authorize_request(request)

            if not permissions.has_org_permission(org_perm, permissions.ORG_STATUS_PAGES_PERMISSION):
                return Response(_lt.get_label(errors.err_subscription_rights, lang), status=403)
            if not permissions.has_user_permission(user_perm, permissions.USER_STATUS_PAGES_PERMISSION):
                return Response(_lt.get_label(errors.err_user_rights, lang), status=403)

            db_status_page_subscribers.delete_status_page_subscriber(
                conn, times.get_current_timestamp(), org_id,
                request.data[var_names.page_ref_id], request.data[var_names.subscribers]
            )
            return Response(_lt.get_label(info.msg_status_page_subscriber_deleted, lang))
        except LookupError as e:
            logging.exception(str(e))
            return Response(_lt.get_label(str(e), lang), status=400)
        except (UnauthorizedRequest, jwt.ExpiredSignatureError, jwt.InvalidSignatureError) as e:
            logging.exception(str(e))
            return Response(_lt.get_label(errors.err_authorization, lang), status=401)
        except Exception as e:
            logging.exception(str(e))
            return Response(_lt.get_label(errors.err_system_error, lang), status=500)
        finally:
            CONN_POOL.put_db_conn(conn)


@api_view(['POST'])
def request_confirmation(request, conn=None):
    '''
    Send a notice requesting the subscriber for confirmation.
    :param request: Http request
    :param conn: db connection
    :return: JSON response -> list
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        expected_fields = [var_names.page_ref_id, var_names.subscriber_ref_id]
        page_ref_id, sub_ref_list = None, []
        try:
            conn = CONN_POOL.get_db_conn() if conn is None else conn
            request_validator.validate_fields(request, expected_fields)
            user_id, org_id, user_perm, org_perm = tokenizer.authorize_request(request)

            if not permissions.has_org_permission(org_perm, permissions.ORG_STATUS_PAGES_PERMISSION):
                return Response(_lt.get_label(errors.err_subscription_rights, lang), status=403)
            if not permissions.has_user_permission(user_perm, permissions.USER_STATUS_PAGES_PERMISSION):
                return Response(_lt.get_label(errors.err_user_rights, lang), status=403)

            page_ref_id = request.data[var_names.page_ref_id]
            sub_ref_list = request.data[var_names.subscriber_ref_id]

            return Response(_lt.get_label(info.msg_status_page_subscriber_invitation_sent, lang))
        except (UnauthorizedRequest, jwt.ExpiredSignatureError, jwt.InvalidSignatureError) as e:
            logging.exception(str(e))
            return Response(_lt.get_label(errors.err_authorization, lang), status=401)
        except Exception as e:
            logging.exception(str(e))
            return Response(_lt.get_label(errors.err_system_error, lang), status=500)
        finally:
            syncer_status_pages.send_status_page_subscriber_confirmation_request(conn, page_ref_id, sub_ref_list)
            CONN_POOL.put_db_conn(conn)
