# -*- 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
from uuid import uuid4
from hashlib import sha256
from http import HTTPStatus
from time import time
from osm_nbi.validation import (
    user_new_schema,
    user_edit_schema,
    project_new_schema,
    project_edit_schema,
    vim_account_new_schema,
    vim_account_edit_schema,
    sdn_new_schema,
    sdn_edit_schema,
    wim_account_new_schema,
    wim_account_edit_schema,
    roles_new_schema,
    roles_edit_schema,
    k8scluster_new_schema,
    k8scluster_edit_schema,
    k8srepo_new_schema,
    k8srepo_edit_schema,
    vca_new_schema,
    vca_edit_schema,
    osmrepo_new_schema,
    osmrepo_edit_schema,
    validate_input,
    ValidationError,
    is_valid_uuid,
)  # To check that User/Project Names don't look like UUIDs
from osm_nbi.base_topic import BaseTopic, EngineException
from osm_nbi.authconn import AuthconnNotFoundException, AuthconnConflictException
from osm_common.dbbase import deep_update_rfc7396
import copy

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


class UserTopic(BaseTopic):
    topic = "users"
    topic_msg = "users"
    schema_new = user_new_schema
    schema_edit = user_edit_schema
    multiproject = False

    def __init__(self, db, fs, msg, auth):
        BaseTopic.__init__(self, db, fs, msg, auth)

    @staticmethod
    def _get_project_filter(session):
        """
        Generates a filter dictionary for querying database users.
        Current policy is admin can show all, non admin, only its own user.
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :return:
        """
        if session["admin"]:  # allows all
            return {}
        else:
            return {"username": session["username"]}

    def check_conflict_on_new(self, session, indata):
        # check username not exists
        if self.db.get_one(
            self.topic,
            {"username": indata.get("username")},
            fail_on_empty=False,
            fail_on_more=False,
        ):
            raise EngineException(
                "username '{}' exists".format(indata["username"]), HTTPStatus.CONFLICT
            )
        # check projects
        if not session["force"]:
            for p in indata.get("projects") or []:
                # To allow project addressing by Name as well as ID
                if not self.db.get_one(
                    "projects",
                    {BaseTopic.id_field("projects", p): p},
                    fail_on_empty=False,
                    fail_on_more=False,
                ):
                    raise EngineException(
                        "project '{}' does not exist".format(p), HTTPStatus.CONFLICT
                    )

    def check_conflict_on_del(self, session, _id, db_content):
        """
        Check if deletion can be done because of dependencies if it is not force. To override
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: internal _id
        :param db_content: The database content of this item _id
        :return: None if ok or raises EngineException with the conflict
        """
        if _id == session["username"]:
            raise EngineException(
                "You cannot delete your own user", http_code=HTTPStatus.CONFLICT
            )

    @staticmethod
    def format_on_new(content, project_id=None, make_public=False):
        BaseTopic.format_on_new(content, make_public=False)
        # Removed so that the UUID is kept, to allow User Name modification
        # content["_id"] = content["username"]
        salt = uuid4().hex
        content["_admin"]["salt"] = salt
        if content.get("password"):
            content["password"] = sha256(
                content["password"].encode("utf-8") + salt.encode("utf-8")
            ).hexdigest()
        if content.get("project_role_mappings"):
            projects = [
                mapping["project"] for mapping in content["project_role_mappings"]
            ]

            if content.get("projects"):
                content["projects"] += projects
            else:
                content["projects"] = projects

    @staticmethod
    def format_on_edit(final_content, edit_content):
        BaseTopic.format_on_edit(final_content, edit_content)
        if edit_content.get("password"):
            salt = uuid4().hex
            final_content["_admin"]["salt"] = salt
            final_content["password"] = sha256(
                edit_content["password"].encode("utf-8") + salt.encode("utf-8")
            ).hexdigest()
        return None

    def edit(self, session, _id, indata=None, kwargs=None, content=None):
        if not session["admin"]:
            raise EngineException(
                "needed admin privileges", http_code=HTTPStatus.UNAUTHORIZED
            )
        # Names that look like UUIDs are not allowed
        name = (indata if indata else kwargs).get("username")
        if is_valid_uuid(name):
            raise EngineException(
                "Usernames that look like UUIDs are not allowed",
                http_code=HTTPStatus.UNPROCESSABLE_ENTITY,
            )
        return BaseTopic.edit(
            self, session, _id, indata=indata, kwargs=kwargs, content=content
        )

    def new(self, rollback, session, indata=None, kwargs=None, headers=None):
        if not session["admin"]:
            raise EngineException(
                "needed admin privileges", http_code=HTTPStatus.UNAUTHORIZED
            )
        # Names that look like UUIDs are not allowed
        name = indata["username"] if indata else kwargs["username"]
        if is_valid_uuid(name):
            raise EngineException(
                "Usernames that look like UUIDs are not allowed",
                http_code=HTTPStatus.UNPROCESSABLE_ENTITY,
            )
        return BaseTopic.new(
            self, rollback, session, indata=indata, kwargs=kwargs, headers=headers
        )


class ProjectTopic(BaseTopic):
    topic = "projects"
    topic_msg = "projects"
    schema_new = project_new_schema
    schema_edit = project_edit_schema
    multiproject = False

    def __init__(self, db, fs, msg, auth):
        BaseTopic.__init__(self, db, fs, msg, auth)

    @staticmethod
    def _get_project_filter(session):
        """
        Generates a filter dictionary for querying database users.
        Current policy is admin can show all, non admin, only its own user.
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :return:
        """
        if session["admin"]:  # allows all
            return {}
        else:
            return {"_id.cont": session["project_id"]}

    def check_conflict_on_new(self, session, indata):
        if not indata.get("name"):
            raise EngineException("missing 'name'")
        # check name not exists
        if self.db.get_one(
            self.topic,
            {"name": indata.get("name")},
            fail_on_empty=False,
            fail_on_more=False,
        ):
            raise EngineException(
                "name '{}' exists".format(indata["name"]), HTTPStatus.CONFLICT
            )

    @staticmethod
    def format_on_new(content, project_id=None, make_public=False):
        BaseTopic.format_on_new(content, None)
        # Removed so that the UUID is kept, to allow Project Name modification
        # content["_id"] = content["name"]

    def check_conflict_on_del(self, session, _id, db_content):
        """
        Check if deletion can be done because of dependencies if it is not force. To override
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: internal _id
        :param db_content: The database content of this item _id
        :return: None if ok or raises EngineException with the conflict
        """
        if _id in session["project_id"]:
            raise EngineException(
                "You cannot delete your own project", http_code=HTTPStatus.CONFLICT
            )
        if session["force"]:
            return
        _filter = {"projects": _id}
        if self.db.get_list("users", _filter):
            raise EngineException(
                "There is some USER that contains this project",
                http_code=HTTPStatus.CONFLICT,
            )

    def edit(self, session, _id, indata=None, kwargs=None, content=None):
        if not session["admin"]:
            raise EngineException(
                "needed admin privileges", http_code=HTTPStatus.UNAUTHORIZED
            )
        # Names that look like UUIDs are not allowed
        name = (indata if indata else kwargs).get("name")
        if is_valid_uuid(name):
            raise EngineException(
                "Project names that look like UUIDs are not allowed",
                http_code=HTTPStatus.UNPROCESSABLE_ENTITY,
            )
        return BaseTopic.edit(
            self, session, _id, indata=indata, kwargs=kwargs, content=content
        )

    def new(self, rollback, session, indata=None, kwargs=None, headers=None):
        if not session["admin"]:
            raise EngineException(
                "needed admin privileges", http_code=HTTPStatus.UNAUTHORIZED
            )
        # Names that look like UUIDs are not allowed
        name = indata["name"] if indata else kwargs["name"]
        if is_valid_uuid(name):
            raise EngineException(
                "Project names that look like UUIDs are not allowed",
                http_code=HTTPStatus.UNPROCESSABLE_ENTITY,
            )
        return BaseTopic.new(
            self, rollback, session, indata=indata, kwargs=kwargs, headers=headers
        )


class CommonVimWimSdn(BaseTopic):
    """Common class for VIM, WIM SDN just to unify methods that are equal to all of them"""

    config_to_encrypt = (
        {}
    )  # what keys at config must be encrypted because contains passwords
    password_to_encrypt = ""  # key that contains a password

    @staticmethod
    def _create_operation(op_type, params=None):
        """
        Creates a dictionary with the information to an operation, similar to ns-lcm-op
        :param op_type: can be create, edit, delete
        :param params: operation input parameters
        :return: new dictionary with
        """
        now = time()
        return {
            "lcmOperationType": op_type,
            "operationState": "PROCESSING",
            "startTime": now,
            "statusEnteredTime": now,
            "detailed-status": "",
            "operationParams": params,
        }

    def check_conflict_on_new(self, session, indata):
        """
        Check that the data to be inserted is valid. It is checked that name is unique
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param indata: data to be inserted
        :return: None or raises EngineException
        """
        self.check_unique_name(session, indata["name"], _id=None)

    def check_conflict_on_edit(self, session, final_content, edit_content, _id):
        """
        Check that the data to be edited/uploaded is valid. It is checked that name is unique
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param final_content: data once modified. This method may change it.
        :param edit_content: incremental data that contains the modifications to apply
        :param _id: internal _id
        :return: None or raises EngineException
        """
        if not session["force"] and edit_content.get("name"):
            self.check_unique_name(session, edit_content["name"], _id=_id)

        return final_content

    def format_on_edit(self, final_content, edit_content):
        """
        Modifies final_content inserting admin information upon edition
        :param final_content: final content to be stored at database
        :param edit_content: user requested update content
        :return: operation id
        """
        super().format_on_edit(final_content, edit_content)

        # encrypt passwords
        schema_version = final_content.get("schema_version")
        if schema_version:
            if edit_content.get(self.password_to_encrypt):
                final_content[self.password_to_encrypt] = self.db.encrypt(
                    edit_content[self.password_to_encrypt],
                    schema_version=schema_version,
                    salt=final_content["_id"],
                )
            config_to_encrypt_keys = self.config_to_encrypt.get(
                schema_version
            ) or self.config_to_encrypt.get("default")
            if edit_content.get("config") and config_to_encrypt_keys:

                for p in config_to_encrypt_keys:
                    if edit_content["config"].get(p):
                        final_content["config"][p] = self.db.encrypt(
                            edit_content["config"][p],
                            schema_version=schema_version,
                            salt=final_content["_id"],
                        )

        # create edit operation
        final_content["_admin"]["operations"].append(self._create_operation("edit"))
        return "{}:{}".format(
            final_content["_id"], len(final_content["_admin"]["operations"]) - 1
        )

    def format_on_new(self, content, project_id=None, make_public=False):
        """
        Modifies content descriptor to include _admin and insert create operation
        :param content: descriptor to be modified
        :param project_id: if included, it add project read/write permissions. Can be None or a list
        :param make_public: if included it is generated as public for reading.
        :return: op_id: operation id on asynchronous operation, None otherwise. In addition content is modified
        """
        super().format_on_new(content, project_id=project_id, make_public=make_public)
        content["schema_version"] = schema_version = "1.11"

        # encrypt passwords
        if content.get(self.password_to_encrypt):
            content[self.password_to_encrypt] = self.db.encrypt(
                content[self.password_to_encrypt],
                schema_version=schema_version,
                salt=content["_id"],
            )
        config_to_encrypt_keys = self.config_to_encrypt.get(
            schema_version
        ) or self.config_to_encrypt.get("default")
        if content.get("config") and config_to_encrypt_keys:
            for p in config_to_encrypt_keys:
                if content["config"].get(p):
                    content["config"][p] = self.db.encrypt(
                        content["config"][p],
                        schema_version=schema_version,
                        salt=content["_id"],
                    )

        content["_admin"]["operationalState"] = "PROCESSING"

        # create operation
        content["_admin"]["operations"] = [self._create_operation("create")]
        content["_admin"]["current_operation"] = None
        # create Resource in Openstack based VIM
        if content.get("vim_type"):
            if content["vim_type"] == "openstack":
                compute = {
                    "ram": {
                        "total": None,
                        "used": None
                    },
                    "vcpus": {
                        "total": None,
                        "used": None
                    },
                    "instances": {
                        "total": None,
                        "used": None
                    }
                }
                storage = {
                    "volumes": {
                        "total": None,
                        "used": None
                    },
                    "snapshots": {
                        "total": None,
                        "used": None
                    },
                    "storage": {
                        "total": None,
                        "used": None
                    }
                }
                network = {
                    "networks": {
                        "total": None,
                        "used": None
                    },
                    "subnets": {
                        "total": None,
                        "used": None
                    },
                    "floating_ips": {
                        "total": None,
                        "used": None
                    }
                }
                content["resources"] = {"compute": compute, "storage": storage, "network": network}


        return "{}:0".format(content["_id"])

    def delete(self, session, _id, dry_run=False, not_send_msg=None):
        """
        Delete item by its internal _id
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: server internal id
        :param dry_run: make checking but do not delete
        :param not_send_msg: To not send message (False) or store content (list) instead
        :return: operation id if it is ordered to delete. None otherwise
        """

        filter_q = self._get_project_filter(session)
        filter_q["_id"] = _id
        db_content = self.db.get_one(self.topic, filter_q)

        self.check_conflict_on_del(session, _id, db_content)
        if dry_run:
            return None

        # remove reference from project_read if there are more projects referencing it. If it last one,
        # do not remove reference, but order via kafka to delete it
        if session["project_id"] and session["project_id"]:
            other_projects_referencing = next(
                (
                    p
                    for p in db_content["_admin"]["projects_read"]
                    if p not in session["project_id"] and p != "ANY"
                ),
                None,
            )

            # check if there are projects referencing it (apart from ANY, that means, public)....
            if other_projects_referencing:
                # remove references but not delete
                update_dict_pull = {
                    "_admin.projects_read": session["project_id"],
                    "_admin.projects_write": session["project_id"],
                }
                self.db.set_one(
                    self.topic, filter_q, update_dict=None, pull_list=update_dict_pull
                )
                return None
            else:
                can_write = next(
                    (
                        p
                        for p in db_content["_admin"]["projects_write"]
                        if p == "ANY" or p in session["project_id"]
                    ),
                    None,
                )
                if not can_write:
                    raise EngineException(
                        "You have not write permission to delete it",
                        http_code=HTTPStatus.UNAUTHORIZED,
                    )

        # It must be deleted
        if session["force"]:
            self.db.del_one(self.topic, {"_id": _id})
            op_id = None
            self._send_msg(
                "deleted", {"_id": _id, "op_id": op_id}, not_send_msg=not_send_msg
            )
        else:
            update_dict = {"_admin.to_delete": True}
            self.db.set_one(
                self.topic,
                {"_id": _id},
                update_dict=update_dict,
                push={"_admin.operations": self._create_operation("delete")},
            )
            # the number of operations is the operation_id. db_content does not contains the new operation inserted,
            # so the -1 is not needed
            op_id = "{}:{}".format(
                db_content["_id"], len(db_content["_admin"]["operations"])
            )
            self._send_msg(
                "delete", {"_id": _id, "op_id": op_id}, not_send_msg=not_send_msg
            )
        return op_id


class VimAccountTopic(CommonVimWimSdn):
    topic = "vim_accounts"
    topic_msg = "vim_account"
    schema_new = vim_account_new_schema
    schema_edit = vim_account_edit_schema
    multiproject = True
    password_to_encrypt = "vim_password"
    config_to_encrypt = {
        "1.1": ("admin_password", "nsx_password", "vcenter_password"),
        "default": (
            "admin_password",
            "nsx_password",
            "vcenter_password",
            "vrops_password",
        ),
    }

    def check_conflict_on_del(self, session, _id, db_content):
        """
        Check if deletion can be done because of dependencies if it is not force. To override
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: internal _id
        :param db_content: The database content of this item _id
        :return: None if ok or raises EngineException with the conflict
        """
        if session["force"]:
            return
        # check if used by VNF
        if self.db.get_list("vnfrs", {"vim-account-id": _id}):
            raise EngineException(
                "There is at least one VNF using this VIM account",
                http_code=HTTPStatus.CONFLICT,
            )
        super().check_conflict_on_del(session, _id, db_content)


class WimAccountTopic(CommonVimWimSdn):
    topic = "wim_accounts"
    topic_msg = "wim_account"
    schema_new = wim_account_new_schema
    schema_edit = wim_account_edit_schema
    multiproject = True
    password_to_encrypt = "wim_password"
    config_to_encrypt = {}


class SdnTopic(CommonVimWimSdn):
    topic = "sdns"
    topic_msg = "sdn"
    quota_name = "sdn_controllers"
    schema_new = sdn_new_schema
    schema_edit = sdn_edit_schema
    multiproject = True
    password_to_encrypt = "password"
    config_to_encrypt = {}

    def _obtain_url(self, input, create):
        if input.get("ip") or input.get("port"):
            if not input.get("ip") or not input.get("port") or input.get("url"):
                raise ValidationError(
                    "You must provide both 'ip' and 'port' (deprecated); or just 'url' (prefered)"
                )
            input["url"] = "http://{}:{}/".format(input["ip"], input["port"])
            del input["ip"]
            del input["port"]
        elif create and not input.get("url"):
            raise ValidationError("You must provide 'url'")
        return input

    def _validate_input_new(self, input, force=False):
        input = super()._validate_input_new(input, force)
        return self._obtain_url(input, True)

    def _validate_input_edit(self, input, content, force=False):
        input = super()._validate_input_edit(input, content, force)
        return self._obtain_url(input, False)


class K8sClusterTopic(CommonVimWimSdn):
    topic = "k8sclusters"
    topic_msg = "k8scluster"
    schema_new = k8scluster_new_schema
    schema_edit = k8scluster_edit_schema
    multiproject = True
    password_to_encrypt = None
    config_to_encrypt = {}

    def format_on_new(self, content, project_id=None, make_public=False):
        oid = super().format_on_new(content, project_id, make_public)
        self.db.encrypt_decrypt_fields(
            content["credentials"],
            "encrypt",
            ["password", "secret"],
            schema_version=content["schema_version"],
            salt=content["_id"],
        )
        # Add Helm/Juju Repo lists
        repos = {"helm-chart": [], "juju-bundle": []}
        for proj in content["_admin"]["projects_read"]:
            if proj != "ANY":
                for repo in self.db.get_list(
                    "k8srepos", {"_admin.projects_read": proj}
                ):
                    if repo["_id"] not in repos[repo["type"]]:
                        repos[repo["type"]].append(repo["_id"])
        for k in repos:
            content["_admin"][k.replace("-", "_") + "_repos"] = repos[k]
        return oid

    def format_on_edit(self, final_content, edit_content):
        if final_content.get("schema_version") and edit_content.get("credentials"):
            self.db.encrypt_decrypt_fields(
                edit_content["credentials"],
                "encrypt",
                ["password", "secret"],
                schema_version=final_content["schema_version"],
                salt=final_content["_id"],
            )
            deep_update_rfc7396(
                final_content["credentials"], edit_content["credentials"]
            )
        oid = super().format_on_edit(final_content, edit_content)
        return oid

    def check_conflict_on_edit(self, session, final_content, edit_content, _id):
        final_content = super(CommonVimWimSdn, self).check_conflict_on_edit(
            session, final_content, edit_content, _id
        )
        final_content = super().check_conflict_on_edit(
            session, final_content, edit_content, _id
        )
        # Update Helm/Juju Repo lists
        repos = {"helm-chart": [], "juju-bundle": []}
        for proj in session.get("set_project", []):
            if proj != "ANY":
                for repo in self.db.get_list(
                    "k8srepos", {"_admin.projects_read": proj}
                ):
                    if repo["_id"] not in repos[repo["type"]]:
                        repos[repo["type"]].append(repo["_id"])
        for k in repos:
            rlist = k.replace("-", "_") + "_repos"
            if rlist not in final_content["_admin"]:
                final_content["_admin"][rlist] = []
            final_content["_admin"][rlist] += repos[k]
        return final_content

    def check_conflict_on_del(self, session, _id, db_content):
        """
        Check if deletion can be done because of dependencies if it is not force. To override
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: internal _id
        :param db_content: The database content of this item _id
        :return: None if ok or raises EngineException with the conflict
        """
        if session["force"]:
            return
        # check if used by VNF
        filter_q = {"kdur.k8s-cluster.id": _id}
        if session["project_id"]:
            filter_q["_admin.projects_read.cont"] = session["project_id"]
        if self.db.get_list("vnfrs", filter_q):
            raise EngineException(
                "There is at least one VNF using this k8scluster",
                http_code=HTTPStatus.CONFLICT,
            )
        super().check_conflict_on_del(session, _id, db_content)


class VcaTopic(CommonVimWimSdn):
    topic = "vca"
    topic_msg = "vca"
    schema_new = vca_new_schema
    schema_edit = vca_edit_schema
    multiproject = True
    password_to_encrypt = None

    def format_on_new(self, content, project_id=None, make_public=False):
        oid = super().format_on_new(content, project_id, make_public)
        content["schema_version"] = schema_version = "1.11"
        for key in ["secret", "cacert"]:
            content[key] = self.db.encrypt(
                content[key], schema_version=schema_version, salt=content["_id"]
            )
        return oid

    def format_on_edit(self, final_content, edit_content):
        oid = super().format_on_edit(final_content, edit_content)
        schema_version = final_content.get("schema_version")
        for key in ["secret", "cacert"]:
            if key in edit_content:
                final_content[key] = self.db.encrypt(
                    edit_content[key],
                    schema_version=schema_version,
                    salt=final_content["_id"],
                )
        return oid

    def check_conflict_on_del(self, session, _id, db_content):
        """
        Check if deletion can be done because of dependencies if it is not force. To override
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: internal _id
        :param db_content: The database content of this item _id
        :return: None if ok or raises EngineException with the conflict
        """
        if session["force"]:
            return
        # check if used by VNF
        filter_q = {"vca": _id}
        if session["project_id"]:
            filter_q["_admin.projects_read.cont"] = session["project_id"]
        if self.db.get_list("vim_accounts", filter_q):
            raise EngineException(
                "There is at least one VIM account using this vca",
                http_code=HTTPStatus.CONFLICT,
            )
        super().check_conflict_on_del(session, _id, db_content)


class K8sRepoTopic(CommonVimWimSdn):
    topic = "k8srepos"
    topic_msg = "k8srepo"
    schema_new = k8srepo_new_schema
    schema_edit = k8srepo_edit_schema
    multiproject = True
    password_to_encrypt = None
    config_to_encrypt = {}

    def format_on_new(self, content, project_id=None, make_public=False):
        oid = super().format_on_new(content, project_id, make_public)
        # Update Helm/Juju Repo lists
        repo_list = content["type"].replace("-", "_") + "_repos"
        for proj in content["_admin"]["projects_read"]:
            if proj != "ANY":
                self.db.set_list(
                    "k8sclusters",
                    {
                        "_admin.projects_read": proj,
                        "_admin." + repo_list + ".ne": content["_id"],
                    },
                    {},
                    push={"_admin." + repo_list: content["_id"]},
                )
        return oid

    def delete(self, session, _id, dry_run=False, not_send_msg=None):
        type = self.db.get_one("k8srepos", {"_id": _id})["type"]
        oid = super().delete(session, _id, dry_run, not_send_msg)
        if oid:
            # Remove from Helm/Juju Repo lists
            repo_list = type.replace("-", "_") + "_repos"
            self.db.set_list(
                "k8sclusters",
                {"_admin." + repo_list: _id},
                {},
                pull={"_admin." + repo_list: _id},
            )
        return oid


class OsmRepoTopic(BaseTopic):
    topic = "osmrepos"
    topic_msg = "osmrepos"
    schema_new = osmrepo_new_schema
    schema_edit = osmrepo_edit_schema
    multiproject = True
    # TODO: Implement user/password


class UserTopicAuth(UserTopic):
    # topic = "users"
    topic_msg = "users"
    schema_new = user_new_schema
    schema_edit = user_edit_schema

    def __init__(self, db, fs, msg, auth):
        UserTopic.__init__(self, db, fs, msg, auth)
        # self.auth = auth

    def check_conflict_on_new(self, session, indata):
        """
        Check that the data to be inserted is valid

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param indata: data to be inserted
        :return: None or raises EngineException
        """
        username = indata.get("username")
        if is_valid_uuid(username):
            raise EngineException(
                "username '{}' cannot have a uuid format".format(username),
                HTTPStatus.UNPROCESSABLE_ENTITY,
            )

        # Check that username is not used, regardless keystone already checks this
        if self.auth.get_user_list(filter_q={"name": username}):
            raise EngineException(
                "username '{}' is already used".format(username), HTTPStatus.CONFLICT
            )

        if "projects" in indata.keys():
            # convert to new format project_role_mappings
            role = self.auth.get_role_list({"name": "project_admin"})
            if not role:
                role = self.auth.get_role_list()
            if not role:
                raise AuthconnNotFoundException(
                    "Can't find default role for user '{}'".format(username)
                )
            rid = role[0]["_id"]
            if not indata.get("project_role_mappings"):
                indata["project_role_mappings"] = []
            for project in indata["projects"]:
                pid = self.auth.get_project(project)["_id"]
                prm = {"project": pid, "role": rid}
                if prm not in indata["project_role_mappings"]:
                    indata["project_role_mappings"].append(prm)
            # raise EngineException("Format invalid: the keyword 'projects' is not allowed for keystone authentication",
            #                       HTTPStatus.BAD_REQUEST)

    def check_conflict_on_edit(self, session, final_content, edit_content, _id):
        """
        Check that the data to be edited/uploaded is valid

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param final_content: data once modified
        :param edit_content: incremental data that contains the modifications to apply
        :param _id: internal _id
        :return: None or raises EngineException
        """

        if "username" in edit_content:
            username = edit_content.get("username")
            if is_valid_uuid(username):
                raise EngineException(
                    "username '{}' cannot have an uuid format".format(username),
                    HTTPStatus.UNPROCESSABLE_ENTITY,
                )

            # Check that username is not used, regardless keystone already checks this
            if self.auth.get_user_list(filter_q={"name": username}):
                raise EngineException(
                    "username '{}' is already used".format(username),
                    HTTPStatus.CONFLICT,
                )

        if final_content["username"] == "admin":
            for mapping in edit_content.get("remove_project_role_mappings", ()):
                if mapping["project"] == "admin" and mapping.get("role") in (
                    None,
                    "system_admin",
                ):
                    # TODO make this also available for project id and role id
                    raise EngineException(
                        "You cannot remove system_admin role from admin user",
                        http_code=HTTPStatus.FORBIDDEN,
                    )

        return final_content

    def check_conflict_on_del(self, session, _id, db_content):
        """
        Check if deletion can be done because of dependencies if it is not force. To override
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: internal _id
        :param db_content: The database content of this item _id
        :return: None if ok or raises EngineException with the conflict
        """
        if db_content["username"] == session["username"]:
            raise EngineException(
                "You cannot delete your own login user ", http_code=HTTPStatus.CONFLICT
            )
        # TODO: Check that user is not logged in ? How? (Would require listing current tokens)

    @staticmethod
    def format_on_show(content):
        """
        Modifies the content of the role information to separate the role
        metadata from the role definition.
        """
        project_role_mappings = []

        if "projects" in content:
            for project in content["projects"]:
                for role in project["roles"]:
                    project_role_mappings.append(
                        {
                            "project": project["_id"],
                            "project_name": project["name"],
                            "role": role["_id"],
                            "role_name": role["name"],
                        }
                    )
            del content["projects"]
        content["project_role_mappings"] = project_role_mappings

        return content

    def new(self, rollback, session, indata=None, kwargs=None, headers=None):
        """
        Creates a new entry into the authentication backend.

        NOTE: Overrides BaseTopic functionality because it doesn't require access to database.

        :param rollback: list to append created items at database in case a rollback may to be done
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :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, operation _id (None)
        """
        try:
            content = BaseTopic._remove_envelop(indata)

            # Override descriptor with query string kwargs
            BaseTopic._update_input_with_kwargs(content, kwargs)
            content = self._validate_input_new(content, session["force"])
            self.check_conflict_on_new(session, content)
            # self.format_on_new(content, session["project_id"], make_public=session["public"])
            now = time()
            content["_admin"] = {"created": now, "modified": now}
            prms = []
            for prm in content.get("project_role_mappings", []):
                proj = self.auth.get_project(prm["project"], not session["force"])
                role = self.auth.get_role(prm["role"], not session["force"])
                pid = proj["_id"] if proj else None
                rid = role["_id"] if role else None
                prl = {"project": pid, "role": rid}
                if prl not in prms:
                    prms.append(prl)
            content["project_role_mappings"] = prms
            # _id = self.auth.create_user(content["username"], content["password"])["_id"]
            _id = self.auth.create_user(content)["_id"]

            rollback.append({"topic": self.topic, "_id": _id})
            # del content["password"]
            self._send_msg("created", content, not_send_msg=None)
            return _id, None
        except ValidationError as e:
            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)

    def show(self, session, _id, filter_q=None, api_req=False):
        """
        Get complete information on an topic

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: server internal id or username
        :param filter_q: dict: query parameter
        :param api_req: True if this call is serving an external API request. False if serving internal request.
        :return: dictionary, raise exception if not found.
        """
        # Allow _id to be a name or uuid
        filter_q = {"username": _id}
        # users = self.auth.get_user_list(filter_q)
        users = self.list(session, filter_q)  # To allow default filtering (Bug 853)
        if len(users) == 1:
            return users[0]
        elif len(users) > 1:
            raise EngineException(
                "Too many users found for '{}'".format(_id), HTTPStatus.CONFLICT
            )
        else:
            raise EngineException(
                "User '{}' not found".format(_id), HTTPStatus.NOT_FOUND
            )

    def edit(self, session, _id, indata=None, kwargs=None, content=None):
        """
        Updates an user entry.

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id:
        :param indata: data to be inserted
        :param kwargs: used to override the indata descriptor
        :param content:
        :return: _id: identity of the inserted data.
        """
        indata = self._remove_envelop(indata)

        # Override descriptor with query string kwargs
        if kwargs:
            BaseTopic._update_input_with_kwargs(indata, kwargs)
        try:
            if not content:
                content = self.show(session, _id)
            indata = self._validate_input_edit(indata, content, force=session["force"])
            content = self.check_conflict_on_edit(session, content, indata, _id=_id)
            # self.format_on_edit(content, indata)

            if not (
                "password" in indata
                or "username" in indata
                or indata.get("remove_project_role_mappings")
                or indata.get("add_project_role_mappings")
                or indata.get("project_role_mappings")
                or indata.get("projects")
                or indata.get("add_projects")
            ):
                return _id
            if indata.get("project_role_mappings") and (
                indata.get("remove_project_role_mappings")
                or indata.get("add_project_role_mappings")
            ):
                raise EngineException(
                    "Option 'project_role_mappings' is incompatible with 'add_project_role_mappings"
                    "' or 'remove_project_role_mappings'",
                    http_code=HTTPStatus.BAD_REQUEST,
                )

            if indata.get("projects") or indata.get("add_projects"):
                role = self.auth.get_role_list({"name": "project_admin"})
                if not role:
                    role = self.auth.get_role_list()
                if not role:
                    raise AuthconnNotFoundException(
                        "Can't find a default role for user '{}'".format(
                            content["username"]
                        )
                    )
                rid = role[0]["_id"]
                if "add_project_role_mappings" not in indata:
                    indata["add_project_role_mappings"] = []
                if "remove_project_role_mappings" not in indata:
                    indata["remove_project_role_mappings"] = []
                if isinstance(indata.get("projects"), dict):
                    # backward compatible
                    for k, v in indata["projects"].items():
                        if k.startswith("$") and v is None:
                            indata["remove_project_role_mappings"].append(
                                {"project": k[1:]}
                            )
                        elif k.startswith("$+"):
                            indata["add_project_role_mappings"].append(
                                {"project": v, "role": rid}
                            )
                    del indata["projects"]
                for proj in indata.get("projects", []) + indata.get("add_projects", []):
                    indata["add_project_role_mappings"].append(
                        {"project": proj, "role": rid}
                    )

            # user = self.show(session, _id)   # Already in 'content'
            original_mapping = content["project_role_mappings"]

            mappings_to_add = []
            mappings_to_remove = []

            # remove
            for to_remove in indata.get("remove_project_role_mappings", ()):
                for mapping in original_mapping:
                    if to_remove["project"] in (
                        mapping["project"],
                        mapping["project_name"],
                    ):
                        if not to_remove.get("role") or to_remove["role"] in (
                            mapping["role"],
                            mapping["role_name"],
                        ):
                            mappings_to_remove.append(mapping)

            # add
            for to_add in indata.get("add_project_role_mappings", ()):
                for mapping in original_mapping:
                    if to_add["project"] in (
                        mapping["project"],
                        mapping["project_name"],
                    ) and to_add["role"] in (
                        mapping["role"],
                        mapping["role_name"],
                    ):

                        if mapping in mappings_to_remove:  # do not remove
                            mappings_to_remove.remove(mapping)
                        break  # do not add, it is already at user
                else:
                    pid = self.auth.get_project(to_add["project"])["_id"]
                    rid = self.auth.get_role(to_add["role"])["_id"]
                    mappings_to_add.append({"project": pid, "role": rid})

            # set
            if indata.get("project_role_mappings"):
                for to_set in indata["project_role_mappings"]:
                    for mapping in original_mapping:
                        if to_set["project"] in (
                            mapping["project"],
                            mapping["project_name"],
                        ) and to_set["role"] in (
                            mapping["role"],
                            mapping["role_name"],
                        ):
                            if mapping in mappings_to_remove:  # do not remove
                                mappings_to_remove.remove(mapping)
                            break  # do not add, it is already at user
                    else:
                        pid = self.auth.get_project(to_set["project"])["_id"]
                        rid = self.auth.get_role(to_set["role"])["_id"]
                        mappings_to_add.append({"project": pid, "role": rid})
                for mapping in original_mapping:
                    for to_set in indata["project_role_mappings"]:
                        if to_set["project"] in (
                            mapping["project"],
                            mapping["project_name"],
                        ) and to_set["role"] in (
                            mapping["role"],
                            mapping["role_name"],
                        ):
                            break
                    else:
                        # delete
                        if mapping not in mappings_to_remove:  # do not remove
                            mappings_to_remove.append(mapping)

            self.auth.update_user(
                {
                    "_id": _id,
                    "username": indata.get("username"),
                    "password": indata.get("password"),
                    "add_project_role_mappings": mappings_to_add,
                    "remove_project_role_mappings": mappings_to_remove,
                }
            )
            data_to_send = {"_id": _id, "changes": indata}
            self._send_msg("edited", data_to_send, not_send_msg=None)

            # return _id
        except ValidationError as e:
            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)

    def list(self, session, filter_q=None, api_req=False):
        """
        Get a list of the topic that matches a filter
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param filter_q: filter of data to be applied
        :param api_req: True if this call is serving an external API request. False if serving internal request.
        :return: The list, it can be empty if no one match the filter.
        """
        user_list = self.auth.get_user_list(filter_q)
        if not session["allow_show_user_project_role"]:
            # Bug 853 - Default filtering
            user_list = [
                usr for usr in user_list if usr["username"] == session["username"]
            ]
        return user_list

    def delete(self, session, _id, dry_run=False, not_send_msg=None):
        """
        Delete item by its internal _id

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: server internal id
        :param force: indicates if deletion must be forced in case of conflict
        :param dry_run: make checking but do not delete
        :param not_send_msg: To not send message (False) or store content (list) instead
        :return: dictionary with deleted item _id. It raises EngineException on error: not found, conflict, ...
        """
        # Allow _id to be a name or uuid
        user = self.auth.get_user(_id)
        uid = user["_id"]
        self.check_conflict_on_del(session, uid, user)
        if not dry_run:
            v = self.auth.delete_user(uid)
            self._send_msg("deleted", user, not_send_msg=not_send_msg)
            return v
        return None


class ProjectTopicAuth(ProjectTopic):
    # topic = "projects"
    topic_msg = "project"
    schema_new = project_new_schema
    schema_edit = project_edit_schema

    def __init__(self, db, fs, msg, auth):
        ProjectTopic.__init__(self, db, fs, msg, auth)
        # self.auth = auth

    def check_conflict_on_new(self, session, indata):
        """
        Check that the data to be inserted is valid

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param indata: data to be inserted
        :return: None or raises EngineException
        """
        project_name = indata.get("name")
        if is_valid_uuid(project_name):
            raise EngineException(
                "project name '{}' cannot have an uuid format".format(project_name),
                HTTPStatus.UNPROCESSABLE_ENTITY,
            )

        project_list = self.auth.get_project_list(filter_q={"name": project_name})

        if project_list:
            raise EngineException(
                "project '{}' exists".format(project_name), HTTPStatus.CONFLICT
            )

    def check_conflict_on_edit(self, session, final_content, edit_content, _id):
        """
        Check that the data to be edited/uploaded is valid

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param final_content: data once modified
        :param edit_content: incremental data that contains the modifications to apply
        :param _id: internal _id
        :return: None or raises EngineException
        """

        project_name = edit_content.get("name")
        if project_name != final_content["name"]:  # It is a true renaming
            if is_valid_uuid(project_name):
                raise EngineException(
                    "project name '{}' cannot have an uuid format".format(project_name),
                    HTTPStatus.UNPROCESSABLE_ENTITY,
                )

            if final_content["name"] == "admin":
                raise EngineException(
                    "You cannot rename project 'admin'", http_code=HTTPStatus.CONFLICT
                )

            # Check that project name is not used, regardless keystone already checks this
            if project_name and self.auth.get_project_list(
                filter_q={"name": project_name}
            ):
                raise EngineException(
                    "project '{}' is already used".format(project_name),
                    HTTPStatus.CONFLICT,
                )
        return final_content

    def check_conflict_on_del(self, session, _id, db_content):
        """
        Check if deletion can be done because of dependencies if it is not force. To override

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: internal _id
        :param db_content: The database content of this item _id
        :return: None if ok or raises EngineException with the conflict
        """

        def check_rw_projects(topic, title, id_field):
            for desc in self.db.get_list(topic):
                if (
                    _id
                    in desc["_admin"]["projects_read"]
                    + desc["_admin"]["projects_write"]
                ):
                    raise EngineException(
                        "Project '{}' ({}) is being used by {} '{}'".format(
                            db_content["name"], _id, title, desc[id_field]
                        ),
                        HTTPStatus.CONFLICT,
                    )

        if _id in session["project_id"]:
            raise EngineException(
                "You cannot delete your own project", http_code=HTTPStatus.CONFLICT
            )

        if db_content["name"] == "admin":
            raise EngineException(
                "You cannot delete project 'admin'", http_code=HTTPStatus.CONFLICT
            )

        # If any user is using this project, raise CONFLICT exception
        if not session["force"]:
            for user in self.auth.get_user_list():
                for prm in user.get("project_role_mappings"):
                    if prm["project"] == _id:
                        raise EngineException(
                            "Project '{}' ({}) is being used by user '{}'".format(
                                db_content["name"], _id, user["username"]
                            ),
                            HTTPStatus.CONFLICT,
                        )

        # If any VNFD, NSD, NST, PDU, etc. is using this project, raise CONFLICT exception
        if not session["force"]:
            check_rw_projects("vnfds", "VNF Descriptor", "id")
            check_rw_projects("nsds", "NS Descriptor", "id")
            check_rw_projects("nsts", "NS Template", "id")
            check_rw_projects("pdus", "PDU Descriptor", "name")

    def new(self, rollback, session, indata=None, kwargs=None, headers=None):
        """
        Creates a new entry into the authentication backend.

        NOTE: Overrides BaseTopic functionality because it doesn't require access to database.

        :param rollback: list to append created items at database in case a rollback may to be done
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :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, operation _id (None)
        """
        try:
            content = BaseTopic._remove_envelop(indata)

            # Override descriptor with query string kwargs
            BaseTopic._update_input_with_kwargs(content, kwargs)
            content = self._validate_input_new(content, session["force"])
            self.check_conflict_on_new(session, content)
            self.format_on_new(
                content, project_id=session["project_id"], make_public=session["public"]
            )
            _id = self.auth.create_project(content)
            rollback.append({"topic": self.topic, "_id": _id})
            self._send_msg("created", content, not_send_msg=None)
            return _id, None
        except ValidationError as e:
            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)

    def show(self, session, _id, filter_q=None, api_req=False):
        """
        Get complete information on an topic

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: server internal id
        :param filter_q: dict: query parameter
        :param api_req: True if this call is serving an external API request. False if serving internal request.
        :return: dictionary, raise exception if not found.
        """
        # Allow _id to be a name or uuid
        filter_q = {self.id_field(self.topic, _id): _id}
        # projects = self.auth.get_project_list(filter_q=filter_q)
        projects = self.list(session, filter_q)  # To allow default filtering (Bug 853)
        if len(projects) == 1:
            return projects[0]
        elif len(projects) > 1:
            raise EngineException("Too many projects found", HTTPStatus.CONFLICT)
        else:
            raise EngineException("Project not found", HTTPStatus.NOT_FOUND)

    def list(self, session, filter_q=None, api_req=False):
        """
        Get a list of the topic that matches a filter

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param filter_q: filter of data to be applied
        :return: The list, it can be empty if no one match the filter.
        """
        project_list = self.auth.get_project_list(filter_q)
        if not session["allow_show_user_project_role"]:
            # Bug 853 - Default filtering
            user = self.auth.get_user(session["username"])
            projects = [prm["project"] for prm in user["project_role_mappings"]]
            project_list = [proj for proj in project_list if proj["_id"] in projects]
        return project_list

    def delete(self, session, _id, dry_run=False, not_send_msg=None):
        """
        Delete item by its internal _id

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: server internal id
        :param dry_run: make checking but do not delete
        :param not_send_msg: To not send message (False) or store content (list) instead
        :return: dictionary with deleted item _id. It raises EngineException on error: not found, conflict, ...
        """
        # Allow _id to be a name or uuid
        proj = self.auth.get_project(_id)
        pid = proj["_id"]
        self.check_conflict_on_del(session, pid, proj)
        if not dry_run:
            v = self.auth.delete_project(pid)
            self._send_msg("deleted", proj, not_send_msg=None)
            return v
        return None

    def edit(self, session, _id, indata=None, kwargs=None, content=None):
        """
        Updates a project entry.

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id:
        :param indata: data to be inserted
        :param kwargs: used to override the indata descriptor
        :param content:
        :return: _id: identity of the inserted data.
        """
        indata = self._remove_envelop(indata)

        # Override descriptor with query string kwargs
        if kwargs:
            BaseTopic._update_input_with_kwargs(indata, kwargs)
        try:
            if not content:
                content = self.show(session, _id)
            indata = self._validate_input_edit(indata, content, force=session["force"])
            content = self.check_conflict_on_edit(session, content, indata, _id=_id)
            self.format_on_edit(content, indata)
            content_original = copy.deepcopy(content)
            deep_update_rfc7396(content, indata)
            self.auth.update_project(content["_id"], content)
            proj_data = {"_id": _id, "changes": indata, "original": content_original}
            self._send_msg("edited", proj_data, not_send_msg=None)
        except ValidationError as e:
            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)


class RoleTopicAuth(BaseTopic):
    topic = "roles"
    topic_msg = None  # "roles"
    schema_new = roles_new_schema
    schema_edit = roles_edit_schema
    multiproject = False

    def __init__(self, db, fs, msg, auth):
        BaseTopic.__init__(self, db, fs, msg, auth)
        # self.auth = auth
        self.operations = auth.role_permissions
        # self.topic = "roles_operations" if isinstance(auth, AuthconnKeystone) else "roles"

    @staticmethod
    def validate_role_definition(operations, role_definitions):
        """
        Validates the role definition against the operations defined in
        the resources to operations files.

        :param operations: operations list
        :param role_definitions: role definition to test
        :return: None if ok, raises ValidationError exception on error
        """
        if not role_definitions.get("permissions"):
            return
        ignore_fields = ["admin", "default"]
        for role_def in role_definitions["permissions"].keys():
            if role_def in ignore_fields:
                continue
            if role_def[-1] == ":":
                raise ValidationError("Operation cannot end with ':'")

            match = next(
                (
                    op
                    for op in operations
                    if op == role_def or op.startswith(role_def + ":")
                ),
                None,
            )

            if not match:
                raise ValidationError("Invalid permission '{}'".format(role_def))

    def _validate_input_new(self, input, force=False):
        """
        Validates input user content for a new entry.

        :param input: user input content for the new topic
        :param force: may be used for being more tolerant
        :return: The same input content, or a changed version of it.
        """
        if self.schema_new:
            validate_input(input, self.schema_new)
            self.validate_role_definition(self.operations, input)

        return input

    def _validate_input_edit(self, input, content, force=False):
        """
        Validates input user content for updating an entry.

        :param input: user input content for the new topic
        :param force: may be used for being more tolerant
        :return: The same input content, or a changed version of it.
        """
        if self.schema_edit:
            validate_input(input, self.schema_edit)
            self.validate_role_definition(self.operations, input)

        return input

    def check_conflict_on_new(self, session, indata):
        """
        Check that the data to be inserted is valid

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param indata: data to be inserted
        :return: None or raises EngineException
        """
        # check name is not uuid
        role_name = indata.get("name")
        if is_valid_uuid(role_name):
            raise EngineException(
                "role name '{}' cannot have an uuid format".format(role_name),
                HTTPStatus.UNPROCESSABLE_ENTITY,
            )
        # check name not exists
        name = indata["name"]
        # if self.db.get_one(self.topic, {"name": indata.get("name")}, fail_on_empty=False, fail_on_more=False):
        if self.auth.get_role_list({"name": name}):
            raise EngineException(
                "role name '{}' exists".format(name), HTTPStatus.CONFLICT
            )

    def check_conflict_on_edit(self, session, final_content, edit_content, _id):
        """
        Check that the data to be edited/uploaded is valid

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param final_content: data once modified
        :param edit_content: incremental data that contains the modifications to apply
        :param _id: internal _id
        :return: None or raises EngineException
        """
        if "default" not in final_content["permissions"]:
            final_content["permissions"]["default"] = False
        if "admin" not in final_content["permissions"]:
            final_content["permissions"]["admin"] = False

        # check name is not uuid
        role_name = edit_content.get("name")
        if is_valid_uuid(role_name):
            raise EngineException(
                "role name '{}' cannot have an uuid format".format(role_name),
                HTTPStatus.UNPROCESSABLE_ENTITY,
            )

        # Check renaming of admin roles
        role = self.auth.get_role(_id)
        if role["name"] in ["system_admin", "project_admin"]:
            raise EngineException(
                "You cannot rename role '{}'".format(role["name"]),
                http_code=HTTPStatus.FORBIDDEN,
            )

        # check name not exists
        if "name" in edit_content:
            role_name = edit_content["name"]
            # if self.db.get_one(self.topic, {"name":role_name,"_id.ne":_id}, fail_on_empty=False, fail_on_more=False):
            roles = self.auth.get_role_list({"name": role_name})
            if roles and roles[0][BaseTopic.id_field("roles", _id)] != _id:
                raise EngineException(
                    "role name '{}' exists".format(role_name), HTTPStatus.CONFLICT
                )

        return final_content

    def check_conflict_on_del(self, session, _id, db_content):
        """
        Check if deletion can be done because of dependencies if it is not force. To override

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: internal _id
        :param db_content: The database content of this item _id
        :return: None if ok or raises EngineException with the conflict
        """
        role = self.auth.get_role(_id)
        if role["name"] in ["system_admin", "project_admin"]:
            raise EngineException(
                "You cannot delete role '{}'".format(role["name"]),
                http_code=HTTPStatus.FORBIDDEN,
            )

        # If any user is using this role, raise CONFLICT exception
        if not session["force"]:
            for user in self.auth.get_user_list():
                for prm in user.get("project_role_mappings"):
                    if prm["role"] == _id:
                        raise EngineException(
                            "Role '{}' ({}) is being used by user '{}'".format(
                                role["name"], _id, user["username"]
                            ),
                            HTTPStatus.CONFLICT,
                        )

    @staticmethod
    def format_on_new(content, project_id=None, make_public=False):  # TO BE REMOVED ?
        """
        Modifies content descriptor to include _admin

        :param content: descriptor to be modified
        :param project_id: if included, it add project read/write permissions
        :param make_public: if included it is generated as public for reading.
        :return: None, but content is modified
        """
        now = time()
        if "_admin" not in content:
            content["_admin"] = {}
        if not content["_admin"].get("created"):
            content["_admin"]["created"] = now
        content["_admin"]["modified"] = now

        if "permissions" not in content:
            content["permissions"] = {}

        if "default" not in content["permissions"]:
            content["permissions"]["default"] = False
        if "admin" not in content["permissions"]:
            content["permissions"]["admin"] = False

    @staticmethod
    def format_on_edit(final_content, edit_content):
        """
        Modifies final_content descriptor to include the modified date.

        :param final_content: final descriptor generated
        :param edit_content: alterations to be include
        :return: None, but final_content is modified
        """
        if "_admin" in final_content:
            final_content["_admin"]["modified"] = time()

        if "permissions" not in final_content:
            final_content["permissions"] = {}

        if "default" not in final_content["permissions"]:
            final_content["permissions"]["default"] = False
        if "admin" not in final_content["permissions"]:
            final_content["permissions"]["admin"] = False
        return None

    def show(self, session, _id, filter_q=None, api_req=False):
        """
        Get complete information on an topic

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: server internal id
        :param filter_q: dict: query parameter
        :param api_req: True if this call is serving an external API request. False if serving internal request.
        :return: dictionary, raise exception if not found.
        """
        filter_q = {BaseTopic.id_field(self.topic, _id): _id}
        # roles = self.auth.get_role_list(filter_q)
        roles = self.list(session, filter_q)  # To allow default filtering (Bug 853)
        if not roles:
            raise AuthconnNotFoundException(
                "Not found any role with filter {}".format(filter_q)
            )
        elif len(roles) > 1:
            raise AuthconnConflictException(
                "Found more than one role with filter {}".format(filter_q)
            )
        return roles[0]

    def list(self, session, filter_q=None, api_req=False):
        """
        Get a list of the topic that matches a filter

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param filter_q: filter of data to be applied
        :return: The list, it can be empty if no one match the filter.
        """
        role_list = self.auth.get_role_list(filter_q)
        if not session["allow_show_user_project_role"]:
            # Bug 853 - Default filtering
            user = self.auth.get_user(session["username"])
            roles = [prm["role"] for prm in user["project_role_mappings"]]
            role_list = [role for role in role_list if role["_id"] in roles]
        return role_list

    def new(self, rollback, session, indata=None, kwargs=None, headers=None):
        """
        Creates a new entry into database.

        :param rollback: list to append created items at database in case a rollback may to be done
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :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, operation _id (None)
        """
        try:
            content = self._remove_envelop(indata)

            # Override descriptor with query string kwargs
            self._update_input_with_kwargs(content, kwargs)
            content = self._validate_input_new(content, session["force"])
            self.check_conflict_on_new(session, content)
            self.format_on_new(
                content, project_id=session["project_id"], make_public=session["public"]
            )
            # role_name = content["name"]
            rid = self.auth.create_role(content)
            content["_id"] = rid
            # _id = self.db.create(self.topic, content)
            rollback.append({"topic": self.topic, "_id": rid})
            # self._send_msg("created", content, not_send_msg=not_send_msg)
            return rid, None
        except ValidationError as e:
            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)

    def delete(self, session, _id, dry_run=False, not_send_msg=None):
        """
        Delete item by its internal _id

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: server internal id
        :param dry_run: make checking but do not delete
        :param not_send_msg: To not send message (False) or store content (list) instead
        :return: dictionary with deleted item _id. It raises EngineException on error: not found, conflict, ...
        """
        filter_q = {BaseTopic.id_field(self.topic, _id): _id}
        roles = self.auth.get_role_list(filter_q)
        if not roles:
            raise AuthconnNotFoundException(
                "Not found any role with filter {}".format(filter_q)
            )
        elif len(roles) > 1:
            raise AuthconnConflictException(
                "Found more than one role with filter {}".format(filter_q)
            )
        rid = roles[0]["_id"]
        self.check_conflict_on_del(session, rid, None)
        # filter_q = {"_id": _id}
        # filter_q = {BaseTopic.id_field(self.topic, _id): _id}   # To allow role addressing by name
        if not dry_run:
            v = self.auth.delete_role(rid)
            # v = self.db.del_one(self.topic, filter_q)
            return v
        return None

    def edit(self, session, _id, indata=None, kwargs=None, content=None):
        """
        Updates a role entry.

        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id:
        :param indata: data to be inserted
        :param kwargs: used to override the indata descriptor
        :param content:
        :return: _id: identity of the inserted data.
        """
        if kwargs:
            self._update_input_with_kwargs(indata, kwargs)
        try:
            if not content:
                content = self.show(session, _id)
            indata = self._validate_input_edit(indata, content, force=session["force"])
            deep_update_rfc7396(content, indata)
            content = self.check_conflict_on_edit(session, content, indata, _id=_id)
            self.format_on_edit(content, indata)
            self.auth.update_role(content)
        except ValidationError as e:
            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
