# By: Riasat Ullah
# This file contains views for handling ServiceNow integration related requests.

from constants import api_paths, label_names as lnm, pages, static_vars, url_paths, var_names
from django.http import JsonResponse
from django.shortcuts import redirect
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, logging, s3
from validations import request_validator
import json
import requests


@require_http_methods(['POST'])
def servicenow_integration_exists(request):
    '''
    Check if an integration with a ServiceNow instance already exists in the organization.
    :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 settings.TEST_MODE:
                if body[var_names.vendor_endpoint] == 'https://dev1234.service-now.com':
                    return JsonResponse(['Ops System Monitor'], safe=False)
                else:
                    return JsonResponse([], safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.integrations_servicenow_instance_exists,
                                                          body, request)
                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_servicenow_integration(request):
    '''
    Handles the first step of the ServiceNow integration process by saving the instance login details in the session.
    :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_name in body and var_names.vendor_endpoint in body\
                    and var_names.username in body and var_names.password in body:
                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_servicenow_meta_data(request):
    '''
    Get available ServiceNow assignment groups.
    :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 in order to facilitate the process set up in the ServiceNow
                # authorization view to avoid have more than one entry for ServiceNow 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:
                output = test_data_services.servicenow_metadata
                if var_names.integration_key not in body:
                    output[var_names.vendor_endpoint] = post_body[var_names.vendor_endpoint]
                    output[var_names.username] = post_body[var_names.username]
                return JsonResponse(test_data_services.servicenow_metadata, safe=False)
            else:
                status, output = helpers.post_api_request(api_paths.integrations_servicenow_instance_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_servicenow_integration(request):
    '''
    Creates a new ServiceNow 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_servicenow 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_servicenow,
                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],
                var_names.external_id:  serv_session[var_names.vendor_endpoint],
                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(lt.get_label(lnm.msg_success, lang), 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_servicenow_integration(request):
    '''
    Edits the configuration of an existing ServiceNow 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(lt.get_label(lnm.msg_success, lang), 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)


@require_http_methods(['POST'])
def update_servicenow_instance_details(request):
    '''
    Update ServiceNow instance details.
    :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_servicenow_instance_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)
