# By: Riasat Ullah
# This file contains code for handling Google Chat configuration pages.

from constants import api_paths, component_names as cnm, label_names as lnm, pages, static_vars, url_paths, var_names
from context_manager import integrations_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 integrations import google_chat
from system_tests.test_data import test_data_services
from taskcallweb import settings
from translators import label_translator as lt
from utils import cdn_enablers, helpers, logging
from validations import request_validator
import json


@require_http_methods(['GET', 'POST'])
def authorize_google_chat_integration(request):
    '''
    Handles the authorization of the Google Chat integration process.
    :param request: Http request
    :return: Http response
    '''
    if request.method == 'GET':
        if var_names.token in request.GET:
            region = request_validator.get_host_region(request)
            verification_token = request.GET[var_names.token]

            if settings.REGION != region and region == static_vars.aws_us_ohio:
                rdr_url = google_chat.get_web_path_us_tc_google_chat_authorization(verification_token)
                return redirect(rdr_url)
            elif settings.REGION == region and region != static_vars.aws_europe_paris:
                # Switch the token to the current server region
                swt_body = {var_names.token: verification_token,
                            var_names.integration_type: static_vars.integ_type_google_chat}
                swt_sts, swt_out = helpers.post_api_request(api_paths.integrations_temporary_token_switch_region,
                                                            swt_body, request)
                logging.info(swt_out)

            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_services, nav_bar_components
                )
                if not has_edit_perm:
                    raise exceptions.PermissionDenied

                body = {var_names.token: verification_token}
                if settings.TEST_MODE:
                    status, output = 200, test_data_services.google_chat_authorization_data
                else:
                    status, output = helpers.post_api_request(api_paths.integrations_google_chat_authorize, body,
                                                              request, lang=lang)

                if status == 200:
                    output = {**output, **{var_names.token: verification_token}}
                    request.session[google_chat.str_google_chat_temp_token_details] = output
                    context = integrations_context.get_google_chat_authorization_context(lang)
                    return render(request, pages.integrations_google_chat_authorization, context=context)
                else:
                    context = {
                        var_names.error_code: 403,
                        var_names.error_message: lt.get_label(lnm.err_google_chat_authorization_token_expired, lang)
                    }
                    return render(request, pages.error_page, context=context)
            else:
                helpers.set_session_redirect_page(request)
                return redirect(pages.login_url)
        else:
            logging.error('Expected parameter "token" is missing. Denying access to Google Chat integration ' +
                          'authorization. Redirecting to login page.')
            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(lt.get_label(lnm.msg_success, lang), status=400, safe=False)
            else:
                body = json.loads(request.body.decode())
                if google_chat.str_google_chat_temp_token_details in request.session and\
                        var_names.integration_name in body and var_names.service_ref_id in body:

                    token_details = request.session[google_chat.str_google_chat_temp_token_details]
                    integ_name = body[var_names.integration_name]
                    serv_ref_id = body[var_names.service_ref_id]

                    post_body = {
                        var_names.service_ref_id: serv_ref_id,
                        var_names.integration_type: static_vars.integ_type_google_chat,
                        var_names.integration_name: integ_name,
                        var_names.additional_info: {
                            var_names.team_id: token_details[google_chat.str_domain_id],
                            var_names.channel_id: token_details[var_names.channel_id]
                        },
                        var_names.external_id: token_details[google_chat.str_domain_id],
                        var_names.external_info: {
                            google_chat.str_domain_id: token_details[google_chat.str_domain_id],
                        }
                    }

                    status, output = helpers.post_api_request(api_paths.services_integrations_add, post_body,
                                                              request, lang=lang)
                    if status == 200:
                        # End-date the temporary token upon successful completion of
                        # the integration so it cannot be reused
                        cnf_body = {var_names.token: token_details[var_names.token],
                                    var_names.channel_id: token_details[var_names.channel_id]}
                        cnf_status, cnf_output = helpers.post_api_request(
                            api_paths.integrations_google_chat_authorize_confirm, cnf_body, request, lang=lang)
                        if cnf_status != 200:
                            logging.error(cnf_output)

                        # If US region, combine Google domain id and channel id in a key and store it in s3. It will
                        # be used as a cache key to identify the region incoming requests should be forwarded to.
                        if settings.REGION == static_vars.aws_us_ohio:
                            cache_key = cdn_enablers.create_cdn_cache_key(
                                static_vars.integ_type_google_chat, token_details[google_chat.str_domain_id],
                                token_details[var_names.channel_id]
                            )
                            if cache_key is not None:
                                cdn_enablers.update_external_account_maps_file(
                                    static_vars.integ_type_google_chat, cache_key)

                        return JsonResponse(url_paths.configurations_services, safe=False)
                    else:
                        logging.info(lnm.err_processing_failed)
                        return JsonResponse(lt.get_label(lnm.err_processing_failed, lang), status=400,
                                            safe=False)
                else:
                    return JsonResponse(lt.get_label(lnm.err_verification_failed, lang), status=400, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)
