#
#   Copyright 2018 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an  BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#

from django.shortcuts import render, redirect
#from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, JsonResponse
import yaml
import json
import logging
from lib.osm.osmclient.clientv2 import Client
from lib.osm.osm_rdcl_parser import OsmParser
import authosm.utils as osmutils
from sf_t3d.decorators import login_required

logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger('instancehandler/view.py')


@login_required
def list(request, type=None):

    user = osmutils.get_user(request)
    project_id = user.project_id
    client = Client()
    result = {'type': type, 'project_id': project_id}
    if "OSM_ERROR" in request.session:
        result['alert_error'] = request.session["OSM_ERROR"]
        del request.session["OSM_ERROR"]
    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
    if 'application/json' not in raw_content_types:
        return __response_handler(request, result, 'instance_list.html')
    instance_list = None
    if type == 'ns':
        instance_list = client.ns_list(user.get_token())
    elif type == 'vnf':
        instance_list = client.vnf_list(user.get_token())

    result['instances'] = instance_list['data'] if instance_list and instance_list['error'] is False else []

    return __response_handler(request, result, 'instance_list.html')


@login_required
def create(request):
    result = {}
    try:

        ns_data = {
            "nsName": request.POST.get('nsName', 'WithoutName'),
            "nsDescription": request.POST.get('nsDescription', ''),
            "nsdId": request.POST.get('nsdId', ''),
            "vimAccountId": request.POST.get('vimAccountId', ''),
        }
        if 'ssh_key' in request.POST and request.POST.get('ssh_key') != '':
            ns_data["ssh_keys"] = [request.POST.get('ssh_key')]

        if 'config' in request.POST:
            ns_config = yaml.load(request.POST.get('config'))
            if isinstance(ns_config, dict):
                if "vim-network-name" in ns_config:
                    ns_config["vld"] = ns_config.pop("vim-network-name")
                if "vld" in ns_config:
                    print ns_config
                    for vld in ns_config["vld"]:
                        if vld.get("vim-network-name"):
                            if isinstance(vld["vim-network-name"], dict):
                                vim_network_name_dict = {}
                                for vim_account, vim_net in vld["vim-network-name"].items():
                                    vim_network_name_dict[ns_data["vimAccountId"]] = vim_net
                                vld["vim-network-name"] = vim_network_name_dict
                    ns_data["vld"] = ns_config["vld"]
                if "vnf" in ns_config:
                    for vnf in ns_config["vnf"]:
                        if vnf.get("vim_account"):
                            vnf["vimAccountId"] = ns_data["vimAccountId"]

                    ns_data["vnf"] = ns_config["vnf"]
    except Exception as e:
        request.session["OSM_ERROR"] = "Error creating the NS; Invalid parameters provided."
        return __response_handler(request, {}, 'instances:list', to_redirect=True, type='ns', )

    print ns_data
    user = osmutils.get_user(request)
    client = Client()
    result = client.ns_create(user.get_token(), ns_data)
    return __response_handler(request, result, 'instances:list', to_redirect=True, type='ns',)


@login_required
def ns_operations(request, instance_id=None, type=None):
    user = osmutils.get_user(request)
    project_id = user.project_id

    result = {'type': 'ns', 'project_id': project_id, 'instance_id': instance_id}
    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
    if 'application/json' not in raw_content_types:
        return __response_handler(request, result, 'instance_operations_list.html')
    client = Client()
    op_list = client.ns_op_list(user.get_token(), instance_id)
    result['operations'] = op_list['data'] if op_list and op_list['error'] is False else []

    return __response_handler(request, result, 'instance_operations_list.html')

@login_required
def ns_operation(request, op_id, instance_id=None, type=None):
    user = osmutils.get_user(request)
    client = Client()
    result = client.ns_op(user.get_token(), op_id)
    return __response_handler(request, result['data'])


@login_required
def action(request, instance_id=None, type=None):
    user = osmutils.get_user(request)
    client = Client()
    # result = client.ns_action(instance_id, action_payload)
    primitive_param_keys = request.POST.getlist('primitive_params_name')
    primitive_param_value = request.POST.getlist('primitive_params_value')
    action_payload = {
        "vnf_member_index": request.POST.get('vnf_member_index'),
        "primitive": request.POST.get('primitive'),
        "primitive_params": {k: v for k, v in zip(primitive_param_keys, primitive_param_value) if len(k) > 0}
    }

    result = client.ns_action(user.get_token(), instance_id, action_payload)
    print result
    if result['error']:
        return __response_handler(request, result['data'], url=None,
                                  status=result['data']['status'] if 'status' in result['data'] else 500)

    else:
        return __response_handler(request, {}, url=None, status=200)


@login_required
def delete(request, instance_id=None, type=None):
    force = bool(request.GET.get('force', False))
    result = {}
    user = osmutils.get_user(request)
    client = Client()
    result = client.ns_delete(user.get_token(), instance_id, force)
    print result
    return __response_handler(request, result, 'instances:list', to_redirect=True, type='ns')

@login_required
def show_topology(request, instance_id=None, type=None):
    user = osmutils.get_user(request)
    project_id = user.project_id
    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
    if 'application/json' in raw_content_types:
        client = Client()
        nsr_object = {'nsr': {}, 'vnfr': {}, 'vnfd': {}}
        if type == 'ns':

            nsr_resp = client.ns_get(user.get_token(), instance_id)
            nsr_object['nsr'] = nsr_resp['data']
            if 'constituent-vnfr-ref' in nsr_object['nsr'] :
                for vnfr_id in nsr_object['nsr']['constituent-vnfr-ref']:
                    vnfr_resp = client.vnf_get(user.get_token(), vnfr_id)
                    vnfr = vnfr_resp['data']
                    nsr_object['vnfr'][vnfr['id']] = vnfr
                    if vnfr['vnfd-id'] not in nsr_object['vnfd']:
                        vnfd_resp = client.vnfd_get(user.get_token(), vnfr['vnfd-id'])
                        nsr_object['vnfd'][vnfr['vnfd-id']] = vnfd_resp['vnfd:vnfd-catalog']['vnfd'][0]



        test = OsmParser()
        #print nsr_object

        result = test.nsr_to_graph(nsr_object)
        return __response_handler(request, result)
    else:
        result = {'type': type, 'project_id': project_id, 'instance_id': instance_id}
        return __response_handler(request, result, 'instance_topology_view.html')


@login_required
def show(request, instance_id=None, type=None):
    # result = {}
    user = osmutils.get_user(request)
    project_id = user.project_id
    client = Client()
    if type == 'ns':
        result = client.ns_get(user.get_token(), instance_id)
    elif type == 'vnf':
        result = client.vnf_get(user.get_token(), instance_id)
    print result
    return __response_handler(request, result)


@login_required
def export_metric(request, instance_id=None, type=None):
    metric_data = request.POST.dict()
    user = osmutils.get_user(request)
    project_id = user.project_id
    client = Client()
    keys = ["collection_period",
            "vnf_member_index",
            "metric_name",
            "correlation_id",
            "vdu_name",
            "collection_unit"]
    metric_data = dict(filter(lambda i: i[0] in keys and len(i[1]) > 0, metric_data.items()))

    result = client.ns_metric_export(user.get_token(), instance_id, metric_data)

    if result['error']:
        print result
        return __response_handler(request, result['data'], url=None,
                                  status=result['data']['status'] if 'status' in result['data'] else 500)
    else:
        return __response_handler(request, {}, url=None, status=200)


@login_required
def create_alarm(request, instance_id=None, type=None):
    metric_data = request.POST.dict()
    print metric_data
    user = osmutils.get_user(request)
    project_id = user.project_id
    client = Client()

    keys = ["threshold_value",
            "vnf_member_index",
            "metric_name",
            "vdu_name",
            "alarm_name",
            "correlation_id",
            "statistic",
            "operation",
            "severity"]
    metric_data = dict(filter(lambda i: i[0] in keys and len(i[1]) > 0, metric_data.items()))

    result = client.ns_alarm_create(user.get_token(), instance_id, metric_data)
    if result['error']:
        print result
        return __response_handler(request, result['data'], url=None,
                                  status=result['data']['status'] if 'status' in result['data'] else 500)
    else:
        return __response_handler(request, {}, url=None, status=200)


def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs):
    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
    if 'application/json' in raw_content_types or url is None:
        return HttpResponse(json.dumps(data_res), content_type="application/json")
    elif to_redirect:
        return redirect(url, *args, **kwargs)
    else:
        return render(request, url, data_res)
