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

from constants import api_paths, label_names as lnm, static_vars, var_names
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from system_tests.test_data import test_data_services
from taskcallweb import settings
from translators import label_translator as lt
from utils import helpers
from validations import request_validator
import json


@require_http_methods(['POST'])
def get_jira_server_hosts(request):
    '''
    Get the list of host addresses of existing Jira servers.
    :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):
            if settings.TEST_MODE:
                return JsonResponse(test_data_services.jira_server_hosts, safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.integrations_jira_server_host, dict(),
                                                          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 get_jira_server_host_details(request):
    '''
    Get the server address and admin username of a Jira Server.
    :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())
            if settings.TEST_MODE:
                return JsonResponse(
                    {var_names.vendor_endpoint: 'http//129.12.89.122:2990', var_names.username: 'admin'},
                    safe=False
                )
            else:
                status, output = helpers.post_api_request(api_paths.integrations_jira_server_host_details, 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 update_jira_server_host_details(request):
    '''
    Update Jira server host credentials.
    :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())
            if settings.TEST_MODE:
                return JsonResponse(True, safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.integrations_jira_server_host_details_update, 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 initiate_jira_server_integration(request):
    '''
    Store Jira Server details and initiate the integration process.
    :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())
            if var_names.integration_name in body and var_names.vendor_endpoint in body:
                # "username" and "password" variables are optional. If they are provided then it must mean that
                # new admin credentials are being provided. If not, then an existing server is being used. This
                # will be handled in the next step of the integration process.
                request.session[var_names.services] = body
                return JsonResponse(lt.get_label(lnm.msg_success, lang), safe=False)
            else:
                return JsonResponse(lt.get_label(lnm.err_invalid_request, lang), status=401, safe=False)
        else:
            return JsonResponse(lt.get_label(lnm.err_unauthorized_access, lang), status=401, safe=False)


@require_http_methods(['POST'])
def get_jira_server_meta_data(request):
    '''
    Get available Jira projects and issue types for Jira server.
    For Jira cloud use the function in jira_cloud_views.
    :param request: Http request
    :return: Http 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())
            if var_names.integration_key in body:
                post_body = body
            else:
                # The code is handled this way here to avoid duplicate entries for the same Jira server host in the
                # organization_integration_type_details table for the same organization.
                serv_session = request.session[var_names.services]
                post_body = {var_names.vendor_endpoint: serv_session[var_names.vendor_endpoint]}

                if var_names.username in serv_session and var_names.password in serv_session:
                    post_body[var_names.username] = serv_session[var_names.username]
                    post_body[var_names.password] = serv_session[var_names.password]

            if settings.TEST_MODE:
                return JsonResponse([test_data_services.jira_projects, test_data_services.jira_issue_types,
                                     test_data_services.jira_statuses], safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.integrations_jira_server_meta_data,
                                                          post_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 create_jira_server_integration(request):
    '''
    Creates a new Jira Server integration.
    :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) and var_names.services in request.session and\
            var_names.integration_type in request.session[var_names.services] and\
            request.session[var_names.services][var_names.integration_type] == static_vars.integ_type_jira_server and\
            var_names.service_ref_id in request.session[var_names.services] and\
                var_names.integration_name in request.session[var_names.services]:

            req_body = json.loads(request.body.decode())
            serv_session = request.session[var_names.services]

            post_body = {
                var_names.service_ref_id: serv_session[var_names.service_ref_id],
                var_names.integration_type: static_vars.integ_type_jira_server,
                var_names.integration_name: serv_session[var_names.integration_name],
                var_names.vendor_endpoint: serv_session[var_names.vendor_endpoint],
                var_names.additional_info: req_body[var_names.additional_info]
            }
            if var_names.username in serv_session or var_names.password in serv_session:
                post_body[var_names.external_id] = serv_session[var_names.vendor_endpoint]
                post_body[var_names.external_info] = {
                    var_names.username: serv_session[var_names.username],
                    var_names.password: serv_session[var_names.password]
                }

            if settings.TEST_MODE:
                return JsonResponse('Action performed successfully', safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.services_integrations_add, post_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 edit_jira_server_integration(request):
    '''
    Edits the configuration of an existing Jira Server integration.
    :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())
            if settings.TEST_MODE:
                return JsonResponse('Action performed successfully', safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.services_integrations_edit, 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)
