# By: Riasat Ullah
# This file contains all general integration related views.

from dbqueries import db_integrations
from rest_framework.decorators import api_view
from rest_framework.response import Response
from taskcallrest import settings
from translators import label_translator as _lt
from utils import constants, errors, info, logging, permissions, times, tokenizer, var_names
from utils.db_connection import CONN_POOL, CONN_CENTRAL_POOL
from validations import request_validator
import configuration
import datetime


@api_view(['POST'])
def available_integrations(request, conn=None):
    '''
    Get all the available and allowed integrations.
    :param request: Http request
    :param conn: db connection
    :return: Http response
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        try:
            conn = CONN_POOL.get_db_conn() if conn is None else conn
            return Response(db_integrations.get_available_integrations(
                conn, times.get_current_timestamp(), only_initiation_needed=False, detailed=True,
                only_service_level=False
            ))
        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 instance_custom_action_integrations(request, conn=None):
    '''
    Get the list of custom actions that can be executed on this instance.
    This identified by the service the instance has occurred on.
    :param request: Http request
    :param conn: db connection
    :return: Http response
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        expected_fields = [var_names.service_ref_id]
        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 permissions.has_org_permission(org_perm, permissions.ORG_INTEGRATION_SECONDARY_PERMISSION):
                return Response(db_integrations.get_instance_custom_action_integrations(
                    conn, times.get_current_timestamp(), org_id, request.data[var_names.service_ref_id]))
            else:
                return Response(_lt.get_label(errors.err_subscription_rights, lang), status=403)
        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 switch_temporary_token_region(request, conn=None, conn_central=None):
    '''
    Switch a temporary token from the central region in EU to the region of this server.
    :param request: Http request
    :param conn: db connection
    :param conn_central: db connection of the central region
    :return: Json response
    '''
    if request.method == 'POST':
        lang = request_validator.get_user_language(request)
        expected_fields = [var_names.token, var_names.integration_type]
        try:
            conn = CONN_POOL.get_db_conn() if conn is None else conn
            conn_central = CONN_CENTRAL_POOL.get_db_conn() if conn_central is None else conn_central
            request_validator.validate_fields(request, expected_fields)
            tokenizer.authorize_request(request)

            if settings.REGION == constants.aws_europe_paris:
                return Response(info.msg_internal_temporary_token_region_switch_unnecessary)

            temp_token = request.data[var_names.token]
            integ_type = request.data[var_names.integration_type]
            current_time = times.get_current_timestamp()

            validity_det = db_integrations.expire_token_and_get_validity_details(
                conn_central, current_time, temp_token, integ_type)
            if validity_det is None:
                return Response(info.msg_internal_temporary_token_region_switch_failed)
            else:
                token_validity_end = validity_det[0] +\
                                     datetime.timedelta(minutes=configuration.temporary_token_lifetime)
                db_integrations.store_temporary_verification_token(conn, validity_det[0], token_validity_end,
                                                                   temp_token, integ_type, validity_det[1])
                return Response(info.msg_internal_temporary_token_region_switched)
        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)
            CONN_CENTRAL_POOL.put_db_conn(conn_central)
