# -*- coding: utf-8 -*-

# 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 logging
import yaml
from osm_common import dbmongo, dbmemory, fslocal, msglocal, msgkafka, version as common_version
from osm_common.dbbase import DbException
from osm_common.fsbase import FsException
from osm_common.msgbase import MsgException
from http import HTTPStatus

from osm_nbi.authconn_keystone import AuthconnKeystone
from osm_nbi.authconn_internal import AuthconnInternal
from osm_nbi.base_topic import EngineException, versiontuple
from osm_nbi.admin_topics import VimAccountTopic, WimAccountTopic, SdnTopic
from osm_nbi.admin_topics import K8sClusterTopic, K8sRepoTopic
from osm_nbi.admin_topics import UserTopicAuth, ProjectTopicAuth, RoleTopicAuth
from osm_nbi.descriptor_topics import VnfdTopic, NsdTopic, PduTopic, NstTopic
from osm_nbi.instance_topics import NsrTopic, VnfrTopic, NsLcmOpTopic, NsiTopic, NsiLcmOpTopic
from osm_nbi.pmjobs_topics import PmJobsTopic
from base64 import b64encode
from os import urandom, path
from threading import Lock

__author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
min_common_version = "0.1.16"


class Engine(object):
    map_from_topic_to_class = {
        "vnfds": VnfdTopic,
        "nsds": NsdTopic,
        "nsts": NstTopic,
        "pdus": PduTopic,
        "nsrs": NsrTopic,
        "vnfrs": VnfrTopic,
        "nslcmops": NsLcmOpTopic,
        "vim_accounts": VimAccountTopic,
        "wim_accounts": WimAccountTopic,
        "sdns": SdnTopic,
        "k8sclusters": K8sClusterTopic,
        "k8srepos": K8sRepoTopic,
        "users": UserTopicAuth,   # Valid for both internal and keystone authentication backends
        "projects": ProjectTopicAuth,   # Valid for both internal and keystone authentication backends
        "roles": RoleTopicAuth,   # Valid for both internal and keystone authentication backends
        "nsis": NsiTopic,
        "nsilcmops": NsiLcmOpTopic
        # [NEW_TOPIC]: add an entry here
        # "pm_jobs": PmJobsTopic will be added manually because it needs other parameters
    }

    map_target_version_to_int = {
        "1.0": 1000,
        "1.1": 1001,
        "1.2": 1002,
        # Add new versions here
    }

    def __init__(self):
        self.db = None
        self.fs = None
        self.msg = None
        self.auth = None
        self.config = None
        self.operations = None
        self.logger = logging.getLogger("nbi.engine")
        self.map_topic = {}
        self.write_lock = None

    def start(self, config):
        """
        Connect to database, filesystem storage, and messaging
        :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
        :return: None
        """
        self.config = config
        # check right version of common
        if versiontuple(common_version) < versiontuple(min_common_version):
            raise EngineException("Not compatible osm/common version '{}'. Needed '{}' or higher".format(
                common_version, min_common_version))

        try:
            if not self.db:
                if config["database"]["driver"] == "mongo":
                    self.db = dbmongo.DbMongo()
                    self.db.db_connect(config["database"])
                elif config["database"]["driver"] == "memory":
                    self.db = dbmemory.DbMemory()
                    self.db.db_connect(config["database"])
                else:
                    raise EngineException("Invalid configuration param '{}' at '[database]':'driver'".format(
                        config["database"]["driver"]))
            if not self.fs:
                if config["storage"]["driver"] == "local":
                    self.fs = fslocal.FsLocal()
                    self.fs.fs_connect(config["storage"])
                else:
                    raise EngineException("Invalid configuration param '{}' at '[storage]':'driver'".format(
                        config["storage"]["driver"]))
            if not self.msg:
                if config["message"]["driver"] == "local":
                    self.msg = msglocal.MsgLocal()
                    self.msg.connect(config["message"])
                elif config["message"]["driver"] == "kafka":
                    self.msg = msgkafka.MsgKafka()
                    self.msg.connect(config["message"])
                else:
                    raise EngineException("Invalid configuration param '{}' at '[message]':'driver'".format(
                        config["message"]["driver"]))
            if not self.auth:
                if config["authentication"]["backend"] == "keystone":
                    self.auth = AuthconnKeystone(config["authentication"], self.db, None)
                else:
                    self.auth = AuthconnInternal(config["authentication"], self.db, dict())
            if not self.operations:
                if "resources_to_operations" in config["rbac"]:
                    resources_to_operations_file = config["rbac"]["resources_to_operations"]
                else:
                    possible_paths = (
                        __file__[:__file__.rfind("engine.py")] + "resources_to_operations.yml",
                        "./resources_to_operations.yml"
                    )
                    for config_file in possible_paths:
                        if path.isfile(config_file):
                            resources_to_operations_file = config_file
                            break
                    if not resources_to_operations_file:                   
                        raise EngineException("Invalid permission configuration: resources_to_operations file missing")

                with open(resources_to_operations_file, 'r') as f:
                    resources_to_operations = yaml.load(f, Loader=yaml.Loader)

                self.operations = []

                for _, value in resources_to_operations["resources_to_operations"].items():
                    if value not in self.operations:
                        self.operations += [value]

            self.write_lock = Lock()
            # create one class per topic
            for topic, topic_class in self.map_from_topic_to_class.items():
                # if self.auth and topic_class in (UserTopicAuth, ProjectTopicAuth):
                #     self.map_topic[topic] = topic_class(self.db, self.fs, self.msg, self.auth)
                if self.auth and topic_class == RoleTopicAuth:
                    self.map_topic[topic] = topic_class(self.db, self.fs, self.msg, self.auth,
                                                        self.operations)
                else:
                    self.map_topic[topic] = topic_class(self.db, self.fs, self.msg, self.auth)
            
            self.map_topic["pm_jobs"] = PmJobsTopic(self.db, config["prometheus"].get("host"),
                                                    config["prometheus"].get("port"))
        except (DbException, FsException, MsgException) as e:
            raise EngineException(str(e), http_code=e.http_code)

    def stop(self):
        try:
            if self.db:
                self.db.db_disconnect()
            if self.fs:
                self.fs.fs_disconnect()
            if self.msg:
                self.msg.disconnect()
            self.write_lock = None
        except (DbException, FsException, MsgException) as e:
            raise EngineException(str(e), http_code=e.http_code)

    def new_item(self, rollback, session, topic, indata=None, kwargs=None, headers=None):
        """
        Creates a new entry into database. For nsds and vnfds it creates an almost empty DISABLED  entry,
        that must be completed with a call to method upload_content
        :param rollback: list to append created items at database in case a rollback must to be done
        :param session: contains the used login username and working project, force to avoid checkins, public
        :param topic: it can be: users, projects, vim_accounts, sdns, nsrs, nsds, vnfds
        :param indata: data to be inserted
        :param kwargs: used to override the indata descriptor
        :param headers: http request headers
        :return: _id: identity of the inserted data.
        """
        if topic not in self.map_topic:
            raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
        with self.write_lock:
            return self.map_topic[topic].new(rollback, session, indata, kwargs, headers)

    def upload_content(self, session, topic, _id, indata, kwargs, headers):
        """
        Upload content for an already created entry (_id)
        :param session: contains the used login username and working project
        :param topic: it can be: users, projects, vnfds, nsds,
        :param _id: server id of the item
        :param indata: data to be inserted
        :param kwargs: used to override the indata descriptor
        :param headers: http request headers
        :return: _id: identity of the inserted data.
        """
        if topic not in self.map_topic:
            raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
        with self.write_lock:
            return self.map_topic[topic].upload_content(session, _id, indata, kwargs, headers)

    def get_item_list(self, session, topic, filter_q=None):
        """
        Get a list of items
        :param session: contains the used login username and working project
        :param topic: it can be: users, projects, vnfds, nsds, ...
        :param filter_q: filter of data to be applied
        :return: The list, it can be empty if no one match the filter_q.
        """
        if topic not in self.map_topic:
            raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
        return self.map_topic[topic].list(session, filter_q)

    def get_item(self, session, topic, _id):
        """
        Get complete information on an item
        :param session: contains the used login username and working project
        :param topic: it can be: users, projects, vnfds, nsds,
        :param _id: server id of the item
        :return: dictionary, raise exception if not found.
        """
        if topic not in self.map_topic:
            raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
        return self.map_topic[topic].show(session, _id)

    def get_file(self, session, topic, _id, path=None, accept_header=None):
        """
        Get descriptor package or artifact file content
        :param session: contains the used login username and working project
        :param topic: it can be: users, projects, vnfds, nsds,
        :param _id: server id of the item
        :param path: artifact path or "$DESCRIPTOR" or None
        :param accept_header: Content of Accept header. Must contain applition/zip or/and text/plain
        :return: opened file plus Accept format or raises an exception
        """
        if topic not in self.map_topic:
            raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
        return self.map_topic[topic].get_file(session, _id, path, accept_header)

    def del_item_list(self, session, topic, _filter=None):
        """
        Delete a list of items
        :param session: contains the used login username and working project
        :param topic: it can be: users, projects, vnfds, nsds, ...
        :param _filter: filter of data to be applied
        :return: The deleted list, it can be empty if no one match the _filter.
        """
        if topic not in self.map_topic:
            raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
        with self.write_lock:
            return self.map_topic[topic].delete_list(session, _filter)

    def del_item(self, session, topic, _id):
        """
        Delete item by its internal id
        :param session: contains the used login username and working project
        :param topic: it can be: users, projects, vnfds, nsds, ...
        :param _id: server id of the item
        :return: dictionary with deleted item _id. It raises exception if not found.
        """
        if topic not in self.map_topic:
            raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
        with self.write_lock:
            return self.map_topic[topic].delete(session, _id)

    def edit_item(self, session, topic, _id, indata=None, kwargs=None):
        """
        Update an existing entry at database
        :param session: contains the used login username and working project
        :param topic: it can be: users, projects, vnfds, nsds, ...
        :param _id: identifier to be updated
        :param indata: data to be inserted
        :param kwargs: used to override the indata descriptor
        :return: dictionary with edited item _id, raise exception if not found.
        """
        if topic not in self.map_topic:
            raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
        with self.write_lock:
            return self.map_topic[topic].edit(session, _id, indata, kwargs)

    def upgrade_db(self, current_version, target_version):
        if target_version not in self.map_target_version_to_int.keys():
            raise EngineException("Cannot upgrade to version '{}' with this version of code".format(target_version),
                                  http_code=HTTPStatus.INTERNAL_SERVER_ERROR)

        if current_version == target_version:
            return
        
        target_version_int = self.map_target_version_to_int[target_version]

        if not current_version:
            # create database version
            serial = urandom(32)
            version_data = {
                "_id": "version",               # Always "version"
                "version_int": 1000,            # version number
                "version": "1.0",               # version text
                "date": "2018-10-25",           # version date
                "description": "added serial",  # changes in this version
                'status': "ENABLED",            # ENABLED, DISABLED (migration in process), ERROR,
                'serial': b64encode(serial)
            }
            self.db.create("admin", version_data)
            self.db.set_secret_key(serial)
            current_version = "1.0"
            
        if current_version in ("1.0", "1.1") and target_version_int >= self.map_target_version_to_int["1.2"]:
            if self.config['authentication']['backend'] == "internal":
                self.db.del_list("roles")

            version_data = {
                "_id": "version",
                "version_int": 1002,
                "version": "1.2",
                "date": "2019-06-11",
                "description": "set new format for roles_operations"
            }

            self.db.set_one("admin", {"_id": "version"}, version_data)
            current_version = "1.2"
            # TODO add future migrations here

    def init_db(self, target_version='1.0'):
        """
        Init database if empty. If not empty it checks that database version and migrates if needed
        If empty, it creates a new user admin/admin at 'users' and a new entry at 'version'
        :param target_version: check desired database version. Migrate to it if possible or raises exception
        :return: None if ok, exception if error or if the version is different.
        """

        version_data = self.db.get_one("admin", {"_id": "version"}, fail_on_empty=False, fail_on_more=True)
        # check database status is ok
        if version_data and version_data.get("status") != 'ENABLED':
            raise EngineException("Wrong database status '{}'".format(
                version_data["status"]), HTTPStatus.INTERNAL_SERVER_ERROR)

        # check version
        db_version = None if not version_data else version_data.get("version")
        if db_version != target_version:
            self.upgrade_db(db_version, target_version)

        return
