#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Copyright 2020 ArctosLabs Scandinavia AB
#
# 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 "AS IS" 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.

import asyncio
import logging
import itertools
from pathlib import Path

import yaml
from osm_common import dbmemory, dbmongo, msglocal, msgkafka

from osm_pla.config.config import Config
from osm_pla.placement.mznplacement import MznPlacementConductor
from osm_pla.placement.mznplacement import NsPlacementDataFactory


class Server:
    pil_price_list_file = Path("/placement/pil_price_list.yaml")
    vnf_price_list_file = Path("/placement/vnf_price_list.yaml")

    def __init__(self, config: Config):
        self.log = logging.getLogger("pla.server")
        self.db = None
        self.msgBus = None
        self.config = config

        try:
            if config.get("database", "driver") == "mongo":
                self.db = dbmongo.DbMongo()
                self.db.db_connect(config.get("database"))
            elif config.get("database", "driver") == "memory":
                self.db = dbmemory.DbMemory()
                self.db.db_connect(config.get("database"))
            else:
                raise Exception(
                    "Invalid configuration param '{}' at '[database]':'driver'".format(
                        config.get("database", "driver")
                    )
                )

            if config.get("message", "driver") == "local":
                self.msgBus = msglocal.MsgLocal()
            elif config.get("message", "driver") == "kafka":
                self.msgBus = msgkafka.MsgKafka()
            else:
                raise Exception(
                    "Invalid message bus driver {}".format(
                        config.get("message", "driver")
                    )
                )
            self.msgBus.connect(config.get("message"))

        except Exception as e:
            self.log.exception("kafka setup error. Exception: {}".format(e))

    def _get_nslcmop(self, nsdlcmop_id):
        """
        :param nsdlcmop_id:
        :return: nslcmop from database corresponding to nslcmop_id
        """
        db_filter = {"_id": nsdlcmop_id}
        nslcmop = self.db.get_one("nslcmops", db_filter)
        return nslcmop

    def _get_projects(self):
        """
        :return: project name to project id mapping
        """
        projects = self.db.get_list("projects")
        return {project["_id"]: project["name"] for project in projects}

    def _get_nsd(self, nsd_id):
        """
        :param nsd_id:
        :return: nsd from database corresponding to nsd_id
        """
        db_filter = {"_id": nsd_id}
        return self.db.get_one("nsds", db_filter)

    def _get_vim_accounts(self, vim_account_ids):
        """
        :param vim_account_ids: list of VIM account ids
        :return: list of vim account entries from database corresponding to list in vim_accounts_id
        """
        db_filter = {"_id": vim_account_ids}
        return self.db.get_list("vim_accounts", db_filter)

    def _read_vnf_price_list(self, price_list_file_path):
        """
        read vnf price list configuration file
        :param price_list_file_path:
        :return:
        """
        with open(str(price_list_file_path)) as pl_fd:
            price_list = yaml.safe_load_all(pl_fd)
            return next(price_list)

    def _price_list_with_project(self, price_list):
        """
        Figure out if this price list is with  project or not.
        Note: to handle the unlikely event that a project is called 'prices' we do not simply check if 'prices'
        is in the dict keys for a price list sequence but rather go down one step in the nesting
        in which we either have
        1) 'prices:{vim_url:...}' if prices are also per project, or
        2) '{vim_url:...}' if prices are only per vim

        :param price_list:
        :return: True if project part of price list, else False
        """
        price_list_entry_keys = set(price_list[0].keys())
        price_list_entry_keys.remove("vnfd")
        pl_key = price_list_entry_keys.pop()
        entry_to_check = price_list[0][pl_key][0].keys()
        return True if "prices" in entry_to_check else False

    def _get_vnf_price_list(self, price_list_file_path, project_name=None):
        """
        read vnf price list configuration file, determine its type and reformat content accordingly

        :param price_list_file_path:
        :param project_name:
        :return: dictionary formatted as {'<vnfd>': {'<vim-url>':'<price>'}}
        """
        price_list_data = self._read_vnf_price_list(price_list_file_path)
        if self._price_list_with_project(price_list_data):
            res = {}
            for i in price_list_data:
                price_data = (
                    i[project_name]
                    if type(i[project_name]) is dict
                    else i[project_name][0]
                )
                res_component = {
                    i["vim_name"]: i["price"] for i in price_data["prices"]
                }
                res.update({i["vnfd"]: res_component})
            return res
        else:
            return {
                i["vnfd"]: {i1["vim_name"]: i1["price"] for i1 in i["prices"]}
                for i in price_list_data
            }

    def _get_pil_info(self, pil_info_file_path):
        """
        read and return pil information from file
        :param pil_info_file_path: Path to pil_info file
        :return pil configuration file content as Python object
        """
        with open(str(pil_info_file_path)) as pil_fd:
            data = yaml.safe_load_all(pil_fd)
            return next(data)

    def _create_vnf_id_maps(self, nsd):
        """
        map identifier for 'member-vnf-index' in nsd to syntax that is safe for mzn

         return tuples with mappings {<adjusted id>: <original id>} and {<original id>: <adjusted id>}
        """
        # TODO: Change for multiple DF support
        ns_df = nsd.get("df", [{}])[0]
        next_idx = itertools.count()
        member_vnf_index2mzn = {
            e["id"]: "VNF" + str(next(next_idx)) for e in ns_df.get("vnf-profile", [])
        }

        # reverse the name map dictionary, used when the placement result is remapped
        mzn_name2member_vnf_index = {v: k for k, v in member_vnf_index2mzn.items()}

        return member_vnf_index2mzn, mzn_name2member_vnf_index

    async def get_placement(self, nslcmop_id):
        """
        - Collects and prepares placement information.
        - Request placement computation.
        - Formats and distribute placement result

        Note: exceptions result in empty response message

        :param nslcmop_id:
        :return:
        """
        try:
            nslcmop = self._get_nslcmop(nslcmop_id)
            nsd = self._get_nsd(nslcmop["operationParams"]["nsdId"])
            member_vnf_index2mzn, mzn2member_vnf_index = self._create_vnf_id_maps(nsd)
            # adjust vnf identifiers
            # TODO: Change for multiple DF support
            ns_df = nsd.get("df", [{}])[0]
            for vnf_profile in ns_df.get("vnf-profile", []):
                vnf_profile["id"] = member_vnf_index2mzn[vnf_profile["id"]]
                for vlc in vnf_profile.get("virtual-link-connectivity", []):
                    for ccpd in vlc.get("constituent-cpd-id", []):
                        ccpd["constituent-base-element-id"] = member_vnf_index2mzn[
                            ccpd["constituent-base-element-id"]
                        ]
            self.log.info("adjusted nsd: {}".format(nsd))
            projects = self._get_projects()
            self.log.info("projects: {}".format(projects))
            nslcmop_project = nslcmop["_admin"]["projects_read"][0]
            self.log.info("nslcmop_project: {}".format(nslcmop_project))
            valid_vim_accounts = nslcmop["operationParams"]["validVimAccounts"]
            vim_accounts_data = self._get_vim_accounts(valid_vim_accounts)
            vims_information = {_["name"]: _["_id"] for _ in vim_accounts_data}
            price_list = self._get_vnf_price_list(
                Server.vnf_price_list_file, projects[nslcmop_project]
            )
            pil_info = self._get_pil_info(Server.pil_price_list_file)
            pinnings = nslcmop["operationParams"].get("vnf", [])
            # remap member-vnf-index values according to id map
            for pinning in pinnings:
                pinning["member-vnf-index"] = member_vnf_index2mzn[
                    pinning["member-vnf-index"]
                ]
            self.log.info("pinnings: {}".format(pinnings))
            order_constraints = nslcmop["operationParams"].get("placement-constraints")
            self.log.info("order constraints: {}".format(order_constraints))

            nspd = NsPlacementDataFactory(
                vims_information, price_list, nsd, pil_info, pinnings, order_constraints
            ).create_ns_placement_data()

            vnf_placement = MznPlacementConductor(self.log).do_placement_computation(
                nspd
            )

        except Exception as e:
            # Note: there is no cure for failure so we have a catch-all clause here
            self.log.exception("PLA fault. Exception: {}".format(e))
            vnf_placement = []
        finally:
            # remap names in vnf_placement
            for e in vnf_placement:
                e["member-vnf-index"] = mzn2member_vnf_index[e["member-vnf-index"]]
            await self.msgBus.aiowrite(
                "pla",
                "placement",
                {"placement": {"vnf": vnf_placement, "nslcmopId": nslcmop_id}},
            )

    def handle_kafka_command(self, topic, command, params):
        self.log.info("Kafka msg arrived: {} {} {}".format(topic, command, params))
        if topic == "pla" and command == "get_placement":
            nslcmop_id = params.get("nslcmopId")
            asyncio.create_task(self.get_placement(nslcmop_id))

    async def kafka_read(self):
        self.log.info("Task kafka_read start")
        while True:
            try:
                topics = "pla"
                await self.msgBus.aioread(topics, self.handle_kafka_command)
            except Exception as e:
                self.log.error("kafka read error. Exception: {}".format(e))
                await asyncio.sleep(5)

    def run(self):
        asyncio.run(self.kafka_read())
        if self.msgBus:
            self.msgBus.disconnect()
