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

from pyrage import x25519
import logging
import random
import string
from uuid import uuid4
from http import HTTPStatus
from time import time
from osm_common.dbbase import deep_update_rfc7396, DbException
from osm_common.msgbase import MsgException
from osm_common.fsbase import FsException
from osm_nbi.validation import validate_input, ValidationError, is_valid_uuid
from yaml import safe_load, YAMLError

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


class EngineException(Exception):
    def __init__(self, message, http_code=HTTPStatus.BAD_REQUEST):
        self.http_code = http_code
        super(Exception, self).__init__(message)


class NBIBadArgumentsException(Exception):
    """
    Bad argument values exception
    """

    def __init__(self, message: str = "", bad_args: list = None):
        Exception.__init__(self, message)
        self.message = message
        self.bad_args = bad_args

    def __str__(self):
        return "{}, Bad arguments: {}".format(self.message, self.bad_args)


def deep_get(target_dict, key_list):
    """
    Get a value from target_dict entering in the nested keys. If keys does not exist, it returns None
    Example target_dict={a: {b: 5}}; key_list=[a,b] returns 5; both key_list=[a,b,c] and key_list=[f,h] return None
    :param target_dict: dictionary to be read
    :param key_list: list of keys to read from  target_dict
    :return: The wanted value if exist, None otherwise
    """
    for key in key_list:
        if not isinstance(target_dict, dict) or key not in target_dict:
            return None
        target_dict = target_dict[key]
    return target_dict


def detect_descriptor_usage(descriptor: dict, db_collection: str, db: object) -> bool:
    """Detect the descriptor usage state.

    Args:
        descriptor (dict):   VNF or NS Descriptor as dictionary
        db_collection (str):   collection name which is looked for in DB
        db (object):   name of db object

    Returns:
        True if descriptor is in use else None

    """
    try:
        if not descriptor:
            raise NBIBadArgumentsException(
                "Argument is mandatory and can not be empty", "descriptor"
            )

        if not db:
            raise NBIBadArgumentsException("A valid DB object should be provided", "db")

        search_dict = {
            "vnfds": ("vnfrs", "vnfd-id"),
            "nsds": ("nsrs", "nsd-id"),
            "ns_config_template": ("ns_config_template", "_id"),
        }

        if db_collection not in search_dict:
            raise NBIBadArgumentsException(
                "db_collection should be equal to vnfds or nsds", "db_collection"
            )

        record_list = db.get_list(
            search_dict[db_collection][0],
            {search_dict[db_collection][1]: descriptor["_id"]},
        )

        if record_list:
            return True

    except (DbException, KeyError, NBIBadArgumentsException) as error:
        raise EngineException(
            f"Error occured while detecting the descriptor usage: {error}"
        )


def update_descriptor_usage_state(
    descriptor: dict, db_collection: str, db: object
) -> None:
    """Updates the descriptor usage state.

    Args:
        descriptor (dict):   VNF or NS Descriptor as dictionary
        db_collection (str):   collection name which is looked for in DB
        db (object):   name of db object

    Returns:
        None

    """
    try:
        descriptor_update = {
            "_admin.usageState": "NOT_IN_USE",
        }

        if detect_descriptor_usage(descriptor, db_collection, db):
            descriptor_update = {
                "_admin.usageState": "IN_USE",
            }

        db.set_one(
            db_collection, {"_id": descriptor["_id"]}, update_dict=descriptor_update
        )

    except (DbException, KeyError, NBIBadArgumentsException) as error:
        raise EngineException(
            f"Error occured while updating the descriptor usage state: {error}"
        )


def get_iterable(input_var):
    """
    Returns an iterable, in case input_var is None it just returns an empty tuple
    :param input_var: can be a list, tuple or None
    :return: input_var or () if it is None
    """
    if input_var is None:
        return ()
    return input_var


def versiontuple(v):
    """utility for compare dot separate versions. Fills with zeros to proper number comparison"""
    filled = []
    for point in v.split("."):
        filled.append(point.zfill(8))
    return tuple(filled)


def increment_ip_mac(ip_mac, vm_index=1):
    if not isinstance(ip_mac, str):
        return ip_mac
    try:
        # try with ipv4 look for last dot
        i = ip_mac.rfind(".")
        if i > 0:
            i += 1
            return "{}{}".format(ip_mac[:i], int(ip_mac[i:]) + vm_index)
        # try with ipv6 or mac look for last colon. Operate in hex
        i = ip_mac.rfind(":")
        if i > 0:
            i += 1
            # format in hex, len can be 2 for mac or 4 for ipv6
            return ("{}{:0" + str(len(ip_mac) - i) + "x}").format(
                ip_mac[:i], int(ip_mac[i:], 16) + vm_index
            )
    except Exception:
        pass
    return None


class BaseTopic:
    # static variables for all instance classes
    topic = None  # to_override
    topic_msg = None  # to_override
    quota_name = None  # to_override. If not provided topic will be used for quota_name
    schema_new = None  # to_override
    schema_edit = None  # to_override
    multiproject = True  # True if this Topic can be shared by several projects. Then it contains _admin.projects_read

    default_quota = 500

    # Alternative ID Fields for some Topics
    alt_id_field = {"projects": "name", "users": "username", "roles": "name"}

    def __init__(self, db, fs, msg, auth):
        self.db = db
        self.fs = fs
        self.msg = msg
        self.logger = logging.getLogger("nbi.base")
        self.auth = auth

    @staticmethod
    def id_field(topic, value):
        """Returns ID Field for given topic and field value"""
        if topic in BaseTopic.alt_id_field.keys() and not is_valid_uuid(value):
            return BaseTopic.alt_id_field[topic]
        else:
            return "_id"

    @staticmethod
    def _remove_envelop(indata=None):
        if not indata:
            return {}
        return indata

    def check_quota(self, session):
        """
        Check whether topic quota is exceeded by the given project
        Used by relevant topics' 'new' function to decide whether or not creation of the new item should be allowed
        :param session[project_id]: projects (tuple) for which quota should be checked
        :param session[force]: boolean. If true, skip quota checking
        :return: None
        :raise:
            DbException if project not found
            ValidationError if quota exceeded in one of the projects
        """
        if session["force"]:
            return
        projects = session["project_id"]
        for project in projects:
            proj = self.auth.get_project(project)
            pid = proj["_id"]
            quota_name = self.quota_name or self.topic
            quota = proj.get("quotas", {}).get(quota_name, self.default_quota)
            count = self.db.count(self.topic, {"_admin.projects_read": pid})
            if count >= quota:
                name = proj["name"]
                raise ValidationError(
                    "quota ({}={}) exceeded for project {} ({})".format(
                        quota_name, quota, name, pid
                    ),
                    http_code=HTTPStatus.UNPROCESSABLE_ENTITY,
                )

    def _validate_input_new(self, input, force=False):
        """
        Validates input user content for a new entry. It uses jsonschema. Some overrides will use pyangbind
        :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)
        return input

    def _validate_input_edit(self, input, content, force=False):
        """
        Validates input user content for an edition. It uses jsonschema. Some overrides will use pyangbind
        :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)
        return input

    @staticmethod
    def _get_project_filter(session):
        """
        Generates a filter dictionary for querying database, so that only allowed items for this project can be
        addressed. Only proprietary or public can be used. Allowed projects are at _admin.project_read/write. If it is
        not present or contains ANY mean public.
        :param session: contains:
            project_id: project list this session has rights to access. Can be empty, one or several
            set_project: items created will contain this project list
            force: True or False
            public: True, False or None
            method: "list", "show", "write", "delete"
            admin: True or False
        :return: dictionary with project filter
        """
        p_filter = {}
        project_filter_n = []
        project_filter = list(session["project_id"])

        if session["method"] not in ("list", "delete"):
            if project_filter:
                project_filter.append("ANY")
        elif session["public"] is not None:
            if session["public"]:
                project_filter.append("ANY")
            else:
                project_filter_n.append("ANY")

        if session.get("PROJECT.ne"):
            project_filter_n.append(session["PROJECT.ne"])

        if project_filter:
            if session["method"] in ("list", "show", "delete") or session.get(
                "set_project"
            ):
                p_filter["_admin.projects_read.cont"] = project_filter
            else:
                p_filter["_admin.projects_write.cont"] = project_filter
        if project_filter_n:
            if session["method"] in ("list", "show", "delete") or session.get(
                "set_project"
            ):
                p_filter["_admin.projects_read.ncont"] = project_filter_n
            else:
                p_filter["_admin.projects_write.ncont"] = project_filter_n

        return p_filter

    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
        """
        pass

    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. This method may change it.
        :param edit_content: incremental data that contains the modifications to apply
        :param _id: internal _id
        :return: final_content or raises EngineException
        """
        if not self.multiproject:
            return final_content
        # Change public status
        if session["public"] is not None:
            if (
                session["public"]
                and "ANY" not in final_content["_admin"]["projects_read"]
            ):
                final_content["_admin"]["projects_read"].append("ANY")
                final_content["_admin"]["projects_write"].clear()
            if (
                not session["public"]
                and "ANY" in final_content["_admin"]["projects_read"]
            ):
                final_content["_admin"]["projects_read"].remove("ANY")

        # Change project status
        if session.get("set_project"):
            for p in session["set_project"]:
                if p not in final_content["_admin"]["projects_read"]:
                    final_content["_admin"]["projects_read"].append(p)

        return final_content

    def check_unique_name(self, session, name, _id=None):
        """
        Check that the name is unique for this project
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param name: name to be checked
        :param _id: If not None, ignore this entry that are going to change
        :return: None or raises EngineException
        """
        if not self.multiproject:
            _filter = {}
        else:
            _filter = self._get_project_filter(session)
        _filter["name"] = name
        if _id:
            _filter["_id.neq"] = _id
        if self.db.get_one(
            self.topic, _filter, fail_on_empty=False, fail_on_more=False
        ):
            raise EngineException(
                "name '{}' already exists for {}".format(name, self.topic),
                HTTPStatus.CONFLICT,
            )

    @staticmethod
    def format_on_new(content, project_id=None, make_public=False):
        """
        Modifies content descriptor to include _admin
        :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
        """
        now = time()
        if "_admin" not in content:
            content["_admin"] = {}
        if not content["_admin"].get("created"):
            content["_admin"]["created"] = now
        content["_admin"]["modified"] = now
        if not content.get("_id"):
            content["_id"] = str(uuid4())
        if project_id is not None:
            if not content["_admin"].get("projects_read"):
                content["_admin"]["projects_read"] = list(project_id)
                if make_public:
                    content["_admin"]["projects_read"].append("ANY")
            if not content["_admin"].get("projects_write"):
                content["_admin"]["projects_write"] = list(project_id)
        return None

    @staticmethod
    def format_on_operation(content, operation_type, operation_params=None):
        op_id = str(uuid4())
        now = time()
        if "operationHistory" not in content:
            content["operationHistory"] = []

        operation = {}
        operation["operationType"] = operation_type
        operation["op_id"] = op_id
        operation["result"] = None
        operation["creationDate"] = now
        operation["endDate"] = None
        operation["workflowState"] = operation["resourceState"] = operation[
            "operationState"
        ] = operation["gitOperationInfo"] = None
        operation["operationParams"] = operation_params

        content["operationHistory"].append(operation)
        return op_id

    @staticmethod
    def format_on_edit(final_content, edit_content):
        """
        Modifies final_content to admin information upon edition
        :param final_content: final content to be stored at database
        :param edit_content: user requested update content
        :return: operation id, if this edit implies an asynchronous operation; None otherwise
        """
        if final_content.get("_admin"):
            now = time()
            final_content["_admin"]["modified"] = now
        return None

    def _send_msg(self, action, content, not_send_msg=None):
        if self.topic_msg and not_send_msg is not False:
            content = content.copy()
            content.pop("_admin", None)
            if isinstance(not_send_msg, list):
                not_send_msg.append((self.topic_msg, action, content))
            else:
                self.msg.write(self.topic_msg, action, 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
        """
        pass

    @staticmethod
    def _update_input_with_kwargs(desc, kwargs, yaml_format=False):
        """
        Update descriptor with the kwargs. It contains dot separated keys
        :param desc: dictionary to be updated
        :param kwargs: plain dictionary to be used for updating.
        :param yaml_format: get kwargs values as yaml format.
        :return: None, 'desc' is modified. It raises EngineException.
        """
        if not kwargs:
            return
        try:
            for k, v in kwargs.items():
                update_content = desc
                kitem_old = None
                klist = k.split(".")
                for kitem in klist:
                    if kitem_old is not None:
                        update_content = update_content[kitem_old]
                    if isinstance(update_content, dict):
                        kitem_old = kitem
                        if not isinstance(update_content.get(kitem_old), (dict, list)):
                            update_content[kitem_old] = {}
                    elif isinstance(update_content, list):
                        # key must be an index of the list, must be integer
                        kitem_old = int(kitem)
                        # if index greater than list, extend the list
                        if kitem_old >= len(update_content):
                            update_content += [None] * (
                                kitem_old - len(update_content) + 1
                            )
                        if not isinstance(update_content[kitem_old], (dict, list)):
                            update_content[kitem_old] = {}
                    else:
                        raise EngineException(
                            "Invalid query string '{}'. Descriptor is not a list nor dict at '{}'".format(
                                k, kitem
                            )
                        )
                if v is None:
                    del update_content[kitem_old]
                else:
                    update_content[kitem_old] = v if not yaml_format else safe_load(v)
        except KeyError:
            raise EngineException(
                "Invalid query string '{}'. Descriptor does not contain '{}'".format(
                    k, kitem_old
                )
            )
        except ValueError:
            raise EngineException(
                "Invalid query string '{}'. Expected integer index list instead of '{}'".format(
                    k, kitem
                )
            )
        except IndexError:
            raise EngineException(
                "Invalid query string '{}'. Index '{}' out of  range".format(
                    k, kitem_old
                )
            )
        except YAMLError:
            raise EngineException("Invalid query string '{}' yaml format".format(k))

    def sol005_projection(self, data):
        # Projection was moved to child classes
        return data

    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.
        """
        if not self.multiproject:
            filter_db = {}
        else:
            filter_db = self._get_project_filter(session)
        # To allow project&user addressing by name AS WELL AS _id
        filter_db[BaseTopic.id_field(self.topic, _id)] = _id
        data = self.db.get_one(self.topic, filter_db)

        # Only perform SOL005 projection if we are serving an external request
        if api_req:
            self.sol005_projection(data)
        return data

        # TODO transform data for SOL005 URL requests
        # TODO remove _admin if not admin

    def get_file(self, session, _id, path=None, accept_header=None):
        """
        Only implemented for descriptor topics. Return the file content of a descriptor
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: Identity of the item to get content
        :param path: artifact path or "$DESCRIPTOR" or None
        :param accept_header: Content of Accept header. Must contain applition/zip or/and text/plain
        :return: opened file or raises an exception
        """
        raise EngineException(
            "Method get_file not valid for this topic", HTTPStatus.INTERNAL_SERVER_ERROR
        )

    def list(self, session, filter_q=None, api_req=False):
        """
        Get a list of the topic that matches a filter
        :param session: contains the used login username and working 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.
        """
        if not filter_q:
            filter_q = {}
        if self.multiproject:
            filter_q.update(self._get_project_filter(session))

        # TODO transform data for SOL005 URL requests. Transform filtering
        # TODO implement "field-type" query string SOL005
        data = self.db.get_list(self.topic, filter_q)

        # Only perform SOL005 projection if we are serving an external request
        if api_req:
            data = [self.sol005_projection(inst) for inst in data]

        return data

    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, op_id:
            _id: identity of the inserted data.
             op_id: operation id if this is asynchronous, None otherwise
        """
        try:
            if self.multiproject:
                self.check_quota(session)

            content = self._remove_envelop(indata)

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

    def upload_content(self, session, _id, indata, kwargs, headers):
        """
        Only implemented for descriptor topics.  Used for receiving content by chunks (with a transaction_id header
        and/or gzip file. It will store and extract)
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id : the database id of entry to be updated
        :param indata: http body request
        :param kwargs: user query string to override parameters. NOT USED
        :param headers:  http request headers
        :return: True package has is completely uploaded or False if partial content has been uplodaed.
            Raise exception on error
        """
        raise EngineException(
            "Method upload_content not valid for this topic",
            HTTPStatus.INTERNAL_SERVER_ERROR,
        )

    def create_gitname(self, content, session, _id=None):
        if not self.multiproject:
            _filter = {}
        else:
            _filter = self._get_project_filter(session)
        _filter["git_name"] = content["name"]
        if _id:
            _filter["_id.neq"] = _id
        if self.db.get_one(
            self.topic, _filter, fail_on_empty=False, fail_on_more=False
        ):
            n = 5
            # using random.choices()
            # generating random strings
            res = "".join(random.choices(string.ascii_lowercase + string.digits, k=n))
            res1 = content["name"]
            new_name1 = res1 + res
            new_name = new_name1.lower()
            return new_name
        else:
            return content["name"]

    def new_profile(self, rollback, session, indata=None, kwargs=None, headers=None):
        step = "name unique check"
        try:
            self.check_unique_name(session, indata["name"])

            step = "validating input parameters"
            profile_request = self._remove_envelop(indata)
            self._update_input_with_kwargs(profile_request, kwargs)
            profile_request = self._validate_input_new(
                profile_request, session["force"]
            )
            operation_params = profile_request

            step = "filling profile details from input data"
            profile_create = self._create_profile(profile_request, session)

            step = "creating profile at database"
            self.format_on_new(
                profile_create, session["project_id"], make_public=session["public"]
            )
            profile_create["current_operation"] = None
            op_id = self.format_on_operation(
                profile_create,
                "create",
                operation_params,
            )

            _id = self.db.create(self.topic, profile_create)
            pubkey, privkey = self._generate_age_key()
            profile_create["age_pubkey"] = self.db.encrypt(
                pubkey, schema_version="1.11", salt=_id
            )
            profile_create["age_privkey"] = self.db.encrypt(
                privkey, schema_version="1.11", salt=_id
            )
            rollback.append({"topic": self.topic, "_id": _id})
            self.db.set_one(self.topic, {"_id": _id}, profile_create)
            if op_id:
                profile_create["op_id"] = op_id
            self._send_msg("profile_create", {"profile_id": _id, "operation_id": op_id})

            return _id, None
        except (
            ValidationError,
            EngineException,
            DbException,
            MsgException,
            FsException,
        ) as e:
            raise type(e)("{} while '{}'".format(e, step), http_code=e.http_code)

    def _create_profile(self, profile_request, session):
        profile_desc = {
            "name": profile_request["name"],
            "description": profile_request["description"],
            "default": False,
            "git_name": self.create_gitname(profile_request, session),
            "state": "IN_CREATION",
            "operatingState": "IN_PROGRESS",
            "resourceState": "IN_PROGRESS.REQUEST_RECEIVED",
        }
        return profile_desc

    def default_profile(
        self, rollback, session, indata=None, kwargs=None, headers=None
    ):
        step = "validating input parameters"
        try:
            profile_request = self._remove_envelop(indata)
            self._update_input_with_kwargs(profile_request, kwargs)
            operation_params = profile_request

            step = "filling profile details from input data"
            profile_create = self._create_default_profile(profile_request, session)

            step = "creating profile at database"
            self.format_on_new(
                profile_create, session["project_id"], make_public=session["public"]
            )
            profile_create["current_operation"] = None
            self.format_on_operation(
                profile_create,
                "create",
                operation_params,
            )
            _id = self.db.create(self.topic, profile_create)
            rollback.append({"topic": self.topic, "_id": _id})
            return _id
        except (
            ValidationError,
            EngineException,
            DbException,
            MsgException,
            FsException,
        ) as e:
            raise type(e)("{} while '{}'".format(e, step), http_code=e.http_code)

    def _create_default_profile(self, profile_request, session):
        profile_desc = {
            "name": profile_request["name"],
            "description": f"{self.topic} profile for cluster {profile_request['name']}",
            "default": True,
            "git_name": self.create_gitname(profile_request, session),
            "state": "IN_CREATION",
            "operatingState": "IN_PROGRESS",
            "resourceState": "IN_PROGRESS.REQUEST_RECEIVED",
        }
        return profile_desc

    def delete_list(self, session, filter_q=None):
        """
        Delete a several entries of a topic. This is for internal usage and test only, not exposed to NBI API
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param filter_q: filter of data to be applied
        :return: The deleted list, it can be empty if no one match the filter.
        """
        # TODO add admin to filter, validate rights
        if not filter_q:
            filter_q = {}
        if self.multiproject:
            filter_q.update(self._get_project_filter(session))
        return self.db.del_list(self.topic, filter_q)

    def delete_extra(self, session, _id, db_content, not_send_msg=None):
        """
        Delete other things apart from database entry of a item _id.
        e.g.: other associated elements at database and other file system storage
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: server internal id
        :param db_content: The database content of the _id. It is already deleted when reached this method, but the
            content is needed in same cases
        :param not_send_msg: To not send message (False) or store content (list) instead
        :return: None if ok or raises EngineException with the problem
        """
        pass

    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 (None if there is not operation), raise exception if error or not found, conflict, ...
        """
        # To allow addressing projects and users by name AS WELL AS by _id
        if not self.multiproject:
            filter_q = {}
        else:
            filter_q = self._get_project_filter(session)
        filter_q[self.id_field(self.topic, _id)] = _id

        item_content = self.db.get_one(self.topic, filter_q)
        nsd_id = item_content.get("_id")

        if (
            self.topic == "k8sinfra_controller"
            or self.topic == "k8sinfra_config"
            or self.topic == "k8sapp"
            or self.topic == "k8sresource"
            or self.topic == "clusters"
        ):
            if "state" in item_content:
                item_content["state"] = "IN_DELETION"
                item_content["operatingState"] = "PROCESSING"
                self.db.set_one(self.topic, {"_id": _id}, item_content)

            item_content_1 = self.db.get_one(self.topic, filter_q)
            item_content_1["current_operation"] = None
            op_id = self.format_on_operation(
                item_content_1,
                "delete",
                None,
            )

        self.check_conflict_on_del(session, _id, item_content)

        # While deteling ns descriptor associated ns config template should also get deleted.
        if self.topic == "nsds":
            ns_config_template_content = self.db.get_list(
                "ns_config_template", {"nsdId": _id}
            )
            for template_content in ns_config_template_content:
                if template_content is not None:
                    if template_content.get("nsdId") == nsd_id:
                        ns_config_template_id = template_content.get("_id")
                        self.db.del_one("ns_config_template", {"nsdId": nsd_id})
                        self.delete_extra(
                            session,
                            ns_config_template_id,
                            template_content,
                            not_send_msg=not_send_msg,
                        )
        if dry_run:
            return None
        if self.multiproject and session["project_id"]:
            # remove reference from project_read if there are more projects referencing it. If it last one,
            # do not remove reference, but delete
            other_projects_referencing = next(
                (
                    p
                    for p in item_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 item_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,
                    )
        # delete
        if (
            self.topic == "k8sinfra_controller"
            or self.topic == "k8sinfra_config"
            or self.topic == "k8sapp"
            or self.topic == "k8sresource"
        ):
            self.db.set_one(self.topic, {"_id": _id}, item_content_1)
            self._send_msg(
                "delete",
                {"profile_id": _id, "operation_id": op_id},
                not_send_msg=not_send_msg,
            )
        elif self.topic == "clusters":
            self.db.set_one("clusters", {"_id": _id}, item_content_1)
            self._send_msg(
                "delete",
                {"cluster_id": _id, "operation_id": op_id},
                not_send_msg=not_send_msg,
            )
        else:
            self.db.del_one(self.topic, filter_q)
            self.delete_extra(session, _id, item_content, not_send_msg=not_send_msg)
            self._send_msg("deleted", {"_id": _id}, not_send_msg=not_send_msg)
        return _id

    def edit(self, session, _id, indata=None, kwargs=None, content=None):
        """
        Change the content of an item
        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
        :param _id: server internal id
        :param indata: contains the changes to apply
        :param kwargs: modifies indata
        :param content: original content of the item
        :return: op_id: operation id if this is processed asynchronously, None otherwise
        """
        indata = self._remove_envelop(indata)

        # Override descriptor with query string kwargs
        if kwargs:
            self._update_input_with_kwargs(indata, kwargs)
        try:
            if (
                self.topic == "k8sinfra_controller"
                or self.topic == "k8sinfra_config"
                or self.topic == "k8sapp"
                or self.topic == "k8sresource"
                or self.topic == "clusters"
            ):
                check = self.db.get_one(self.topic, {"_id": _id})
                if self.topic != "clusters":
                    if check["default"] is True:
                        raise EngineException(
                            "Cannot edit default profiles",
                            HTTPStatus.UNPROCESSABLE_ENTITY,
                        )
                if "name" in indata:
                    if check["name"] == indata["name"]:
                        pass
                    else:
                        self.check_unique_name(session, indata["name"])
            if indata and session.get("set_project"):
                raise EngineException(
                    "Cannot edit content and set to project (query string SET_PROJECT) at same time",
                    HTTPStatus.UNPROCESSABLE_ENTITY,
                )
            # TODO self._check_edition(session, indata, _id, force)
            if not content:
                content = self.show(session, _id)
            indata = self._validate_input_edit(indata, content, force=session["force"])
            deep_update_rfc7396(content, indata)

            # To allow project addressing by name AS WELL AS _id. Get the _id, just in case the provided one is a name
            _id = content.get("_id") or _id

            content = self.check_conflict_on_edit(session, content, indata, _id=_id)
            op_id = self.format_on_edit(content, indata)

            self.db.replace(self.topic, _id, content)

            indata.pop("_admin", None)
            if op_id:
                indata["op_id"] = op_id
            indata["_id"] = _id
            if (
                self.topic == "k8sinfra_controller"
                or self.topic == "k8sinfra_config"
                or self.topic == "k8sapp"
                or self.topic == "k8sresource"
                or self.topic == "clusters"
            ):
                pass
            else:
                self._send_msg("edited", indata)
            return op_id
        except ValidationError as e:
            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)

    def detach(self, session, _id, profile_type):
        # To detach the profiles from every cluster
        filter_q = {}
        existing_clusters = self.db.get_list("clusters", filter_q)
        existing_clusters_profiles = [
            profile["_id"]
            for profile in existing_clusters
            if profile.get("profile_type", _id)
        ]
        update_dict = None
        for profile in existing_clusters_profiles:
            filter_q = {"_id": profile}
            data = self.db.get_one("clusters", filter_q)
            if profile_type in data:
                profile_ids = data[profile_type]
                if _id in profile_ids:
                    profile_ids.remove(_id)
                    update_dict = {profile_type: profile_ids}
                    self.db.set_one("clusters", filter_q, update_dict)

    def _generate_age_key(self):
        ident = x25519.Identity.generate()
        # gets the public key
        pubkey = str(ident.to_public())
        # gets the private key
        privkey = str(ident)
        # return both public and private key
        return pubkey, privkey
