# -*- 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

        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)
