# By: Riasat Ullah
# This file contains views for handling Webex authorization pages.

from constants import api_paths, label_names as lnm, pages, static_vars, var_names
from django.shortcuts import redirect
from django.views.decorators.http import require_http_methods
from integrations import webex
from taskcallweb import settings
from translators import label_translator as lt
from utils import helpers, logging
from validations import request_validator
import requests


@require_http_methods(['GET'])
def authorize_webex_integration(request):
    '''
    Handles the authorization of the Webex integration process.
    :param request: Http request
    :return: Http response
    '''
    logging.info(request.GET)
    if request.method == 'GET':
        if 'error' in request.GET:
            if 'error_description' in request.GET:
                err_desc = request.GET['error_description']
            else:
                err_desc = request.GET['error']
            logging.error(err_desc)
            url_to_send_to = pages.conference_bridges_url + '?error=' + err_desc
            return redirect(url_to_send_to)
        elif 'code' not in request.GET and 'state' not in request.GET:
            logging.error('Expected parameters "code" and "state" are missing. Denying access to Webex integration ' +
                          'authorization. Redirecting to login page.')
            return redirect(pages.login_url)
        else:
            code = request.GET['code']
            state = request.GET['state']

            if not request_validator.user_in_session(request) or \
                (var_names.conference_bridges not in request.session
                 and var_names.state not in request.session[var_names.conference_bridges]
                 and not (var_names.conference_name in request.session[var_names.conference_bridges] or
                          var_names.integration_type in request.session[var_names.conference_bridges]))\
                    and request.session[var_names.conference_bridges][var_names.integration_type]\
                    != static_vars.integ_type_webex:

                logging.error('Expected service session variables were not found. Denying access ' +
                              'to webex integration authorization. Redirecting to login page.')
                return redirect(pages.login_url)
            else:
                lang = request_validator.get_user_language(request)
                conf_session = request.session[var_names.conference_bridges]
                failed = True

                if state == conf_session[var_names.state]:
                    try:
                        webex_creds = webex.get_webex_credentials()
                        post_body = {
                            var_names.grant_type: 'authorization_code',
                            var_names.client_id: webex_creds[var_names.client_id],
                            var_names.client_secret: webex_creds[var_names.client_secret],
                            var_names.code: code,
                            var_names.redirect_uri: webex.get_webex_to_tc_redirect_uri()
                        }

                        # Get Webex authorization and refresh tokens.
                        oauth_resp = requests.post(webex.webex_token_retrieval_path, json=post_body)
                        if oauth_resp.status_code == 200:
                            oauth_data = oauth_resp.json()
                            logging.info(oauth_data)

                            access_token = oauth_data[var_names.access_token]
                            refresh_token = oauth_data[var_names.refresh_token]

                            # get the Webex organization ID with the access token
                            webex_org_resp = requests.get(
                                webex.webex_organizations_path,
                                headers={"Authorization": "Bearer " + access_token, "Accept": "application/json"}
                            )
                            if webex_org_resp.status_code == 200:
                                webex_org_id = webex_org_resp.json()['items'][0]['id']
                                if settings.TEST_MODE:
                                    failed = False
                                else:
                                    final_body = {
                                        var_names.conference_name: conf_session[var_names.conference_name],
                                        var_names.integration_type: static_vars.integ_type_webex,
                                        var_names.external_id: webex_org_id,
                                        var_names.external_info: {
                                            var_names.access_token: access_token,
                                            var_names.refresh_token: refresh_token
                                        }
                                    }
                                    final_status, final_output = helpers.post_api_request(
                                        api_paths.conference_bridges_create, final_body, request, lang=lang)
                                    if final_status == 200:
                                        failed = False
                                        del request.session[var_names.conference_bridges]

                    except Exception as e:
                        logging.exception(str(e))

                if failed:
                    logging.exception(lnm.err_verification_failed)
                    return redirect(pages.conference_bridges_url + '?error=' +
                                    lt.get_label(lnm.err_unauthorized_access, lang))
                else:
                    return redirect(pages.conference_bridges_url)
