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

# Copyright 2018 Telefonica S.A.
# Copyright 2018 ALTRAN Innovación S.L.
#
# 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.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact: esousa@whitestack.com or glavado@whitestack.com
##

"""
AuthconnInternal implements implements the connector for
OSM Internal Authentication Backend and leverages the RBAC model
"""

__author__ = (
    "Pedro de la Cruz Ramos <pdelacruzramos@altran.com>, "
    "Alfonso Tierno <alfonso.tiernosepulveda@telefoncia.com"
)
__date__ = "$06-jun-2019 11:16:08$"

import logging
import re

from osm_nbi.authconn import Authconn, AuthException  # , AuthconnOperationException
from osm_common.dbbase import DbException
from osm_nbi.base_topic import BaseTopic
from osm_nbi.validation import is_valid_uuid
from time import time, sleep
from http import HTTPStatus
from uuid import uuid4
from hashlib import sha256
from copy import deepcopy
from random import choice as random_choice


class AuthconnInternal(Authconn):
    token_time_window = 2  # seconds
    token_delay = 1  # seconds to wait upon second request within time window

    users_collection = "users"
    roles_collection = "roles"
    projects_collection = "projects"
    tokens_collection = "tokens"

    def __init__(self, config, db, role_permissions):
        Authconn.__init__(self, config, db, role_permissions)
        self.logger = logging.getLogger("nbi.authenticator.internal")

        self.db = db
        # self.msg = msg
        # self.token_cache = token_cache

        # To be Confirmed
        self.sess = None

    def validate_token(self, token):
        """
        Check if the token is valid.

        :param token: token to validate
        :return: dictionary with information associated with the token:
            "_id": token id
            "project_id": project id
            "project_name": project name
            "user_id": user id
            "username": user name
            "roles": list with dict containing {name, id}
            "expires": expiration date
        If the token is not valid an exception is raised.
        """

        try:
            if not token:
                raise AuthException(
                    "Needed a token or Authorization HTTP header",
                    http_code=HTTPStatus.UNAUTHORIZED,
                )

            now = time()

            # get from database if not in cache
            # if not token_info:
            token_info = self.db.get_one(self.tokens_collection, {"_id": token})
            if token_info["expires"] < now:
                raise AuthException(
                    "Expired Token or Authorization HTTP header",
                    http_code=HTTPStatus.UNAUTHORIZED,
                )

            return token_info

        except DbException as e:
            if e.http_code == HTTPStatus.NOT_FOUND:
                raise AuthException(
                    "Invalid Token or Authorization HTTP header",
                    http_code=HTTPStatus.UNAUTHORIZED,
                )
            else:
                raise
        except AuthException:
            raise
        except Exception:
            self.logger.exception(
                "Error during token validation using internal backend"
            )
            raise AuthException(
                "Error during token validation using internal backend",
                http_code=HTTPStatus.UNAUTHORIZED,
            )

    def revoke_token(self, token):
        """
        Invalidate a token.

        :param token: token to be revoked
        """
        try:
            # self.token_cache.pop(token, None)
            self.db.del_one(self.tokens_collection, {"_id": token})
            return True
        except DbException as e:
            if e.http_code == HTTPStatus.NOT_FOUND:
                raise AuthException(
                    "Token '{}' not found".format(token), http_code=HTTPStatus.NOT_FOUND
                )
            else:
                # raise
                exmsg = "Error during token revocation using internal backend"
                self.logger.exception(exmsg)
                raise AuthException(exmsg, http_code=HTTPStatus.UNAUTHORIZED)

    def validate_user(self, user, password):
        """
        Validate username and password via appropriate backend.
        :param user: username of the user.
        :param password: password to be validated.
        """
        user_rows = self.db.get_list(
            self.users_collection, {BaseTopic.id_field("users", user): user}
        )
        user_content = None
        if user_rows:
            user_content = user_rows[0]
            salt = user_content["_admin"]["salt"]
            shadow_password = sha256(
                password.encode("utf-8") + salt.encode("utf-8")
            ).hexdigest()
            if shadow_password != user_content["password"]:
                user_content = None
        return user_content

    def authenticate(self, credentials, token_info=None):
        """
        Authenticate a user using username/password or previous token_info plus project; its creates a new token

        :param credentials: dictionary that contains:
            username: name, id or None
            password: password or None
            project_id: name, id, or None. If None first found project will be used to get an scope token
            other items are allowed and ignored
        :param token_info: previous token_info to obtain authorization
        :return: the scoped token info or raises an exception. The token is a dictionary with:
            _id:  token string id,
            username: username,
            project_id: scoped_token project_id,
            project_name: scoped_token project_name,
            expires: epoch time when it expires,
        """

        now = time()
        user_content = None
        user = credentials.get("username")
        password = credentials.get("password")
        project = credentials.get("project_id")

        # Try using username/password
        if user:
            user_content = self.validate_user(user, password)
            if not user_content:
                raise AuthException(
                    "Invalid username/password", http_code=HTTPStatus.UNAUTHORIZED
                )
            if not user_content.get("_admin", None):
                raise AuthException(
                    "No default project for this user.",
                    http_code=HTTPStatus.UNAUTHORIZED,
                )
        elif token_info:
            user_rows = self.db.get_list(
                self.users_collection, {"username": token_info["username"]}
            )
            if user_rows:
                user_content = user_rows[0]
            else:
                raise AuthException("Invalid token", http_code=HTTPStatus.UNAUTHORIZED)
        else:
            raise AuthException(
                "Provide credentials: username/password or Authorization Bearer token",
                http_code=HTTPStatus.UNAUTHORIZED,
            )
        # Delay upon second request within time window
        if (
            now - user_content["_admin"].get("last_token_time", 0)
            < self.token_time_window
        ):
            sleep(self.token_delay)
        # user_content["_admin"]["last_token_time"] = now
        # self.db.replace("users", user_content["_id"], user_content)   # might cause race conditions
        self.db.set_one(
            self.users_collection,
            {"_id": user_content["_id"]},
            {"_admin.last_token_time": now},
        )

        token_id = "".join(
            random_choice(
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
            )
            for _ in range(0, 32)
        )

        # projects = user_content.get("projects", [])
        prm_list = user_content.get("project_role_mappings", [])

        if not project:
            project = prm_list[0]["project"] if prm_list else None
        if not project:
            raise AuthException(
                "can't find a default project for this user",
                http_code=HTTPStatus.UNAUTHORIZED,
            )

        projects = [prm["project"] for prm in prm_list]

        proj = self.db.get_one(
            self.projects_collection, {BaseTopic.id_field("projects", project): project}
        )
        project_name = proj["name"]
        project_id = proj["_id"]
        if project_name not in projects and project_id not in projects:
            raise AuthException(
                "project {} not allowed for this user".format(project),
                http_code=HTTPStatus.UNAUTHORIZED,
            )

        # TODO remove admin, this vill be used by roles RBAC
        if project_name == "admin":
            token_admin = True
        else:
            token_admin = proj.get("admin", False)

        # add token roles
        roles = []
        roles_list = []
        for prm in prm_list:
            if prm["project"] in [project_id, project_name]:
                role = self.db.get_one(
                    self.roles_collection,
                    {BaseTopic.id_field("roles", prm["role"]): prm["role"]},
                )
                rid = role["_id"]
                if rid not in roles:
                    rnm = role["name"]
                    roles.append(rid)
                    roles_list.append({"name": rnm, "id": rid})
        if not roles_list:
            rid = self.db.get_one(self.roles_collection, {"name": "project_admin"})[
                "_id"
            ]
            roles_list = [{"name": "project_admin", "id": rid}]

        new_token = {
            "issued_at": now,
            "expires": now + 3600,
            "_id": token_id,
            "id": token_id,
            "project_id": proj["_id"],
            "project_name": proj["name"],
            "username": user_content["username"],
            "user_id": user_content["_id"],
            "admin": token_admin,
            "roles": roles_list,
        }

        self.db.create(self.tokens_collection, new_token)
        return deepcopy(new_token)

    def get_role_list(self, filter_q={}):
        """
        Get role list.

        :return: returns the list of roles.
        """
        return self.db.get_list(self.roles_collection, filter_q)

    def create_role(self, role_info):
        """
        Create a role.

        :param role_info: full role info.
        :return: returns the role id.
        :raises AuthconnOperationException: if role creation failed.
        """
        # TODO: Check that role name does not exist ?
        rid = str(uuid4())
        role_info["_id"] = rid
        rid = self.db.create(self.roles_collection, role_info)
        return rid

    def delete_role(self, role_id):
        """
        Delete a role.

        :param role_id: role identifier.
        :raises AuthconnOperationException: if role deletion failed.
        """
        rc = self.db.del_one(self.roles_collection, {"_id": role_id})
        self.db.del_list(self.tokens_collection, {"roles.id": role_id})
        return rc

    def update_role(self, role_info):
        """
        Update a role.

        :param role_info: full role info.
        :return: returns the role name and id.
        :raises AuthconnOperationException: if user creation failed.
        """
        rid = role_info["_id"]
        self.db.set_one(self.roles_collection, {"_id": rid}, role_info)
        return {"_id": rid, "name": role_info["name"]}

    def create_user(self, user_info):
        """
        Create a user.

        :param user_info: full user info.
        :return: returns the username and id of the user.
        """
        BaseTopic.format_on_new(user_info, make_public=False)
        salt = uuid4().hex
        user_info["_admin"]["salt"] = salt
        if "password" in user_info:
            user_info["password"] = sha256(
                user_info["password"].encode("utf-8") + salt.encode("utf-8")
            ).hexdigest()
        # "projects" are not stored any more
        if "projects" in user_info:
            del user_info["projects"]
        self.db.create(self.users_collection, user_info)
        return {"username": user_info["username"], "_id": user_info["_id"]}

    def update_user(self, user_info):
        """
        Change the user name and/or password.

        :param user_info: user info modifications
        """
        uid = user_info["_id"]
        user_data = self.db.get_one(
            self.users_collection, {BaseTopic.id_field("users", uid): uid}
        )
        BaseTopic.format_on_edit(user_data, user_info)
        # User Name
        usnm = user_info.get("username")
        if usnm:
            user_data["username"] = usnm
        # If password is given and is not already encripted
        pswd = user_info.get("password")
        if pswd and (
            len(pswd) != 64 or not re.match("[a-fA-F0-9]*", pswd)
        ):  # TODO: Improve check?
            salt = uuid4().hex
            if "_admin" not in user_data:
                user_data["_admin"] = {}
            user_data["_admin"]["salt"] = salt
            user_data["password"] = sha256(
                pswd.encode("utf-8") + salt.encode("utf-8")
            ).hexdigest()
        # Project-Role Mappings
        # TODO: Check that user_info NEVER includes "project_role_mappings"
        if "project_role_mappings" not in user_data:
            user_data["project_role_mappings"] = []
        for prm in user_info.get("add_project_role_mappings", []):
            user_data["project_role_mappings"].append(prm)
        for prm in user_info.get("remove_project_role_mappings", []):
            for pidf in ["project", "project_name"]:
                for ridf in ["role", "role_name"]:
                    try:
                        user_data["project_role_mappings"].remove(
                            {"role": prm[ridf], "project": prm[pidf]}
                        )
                    except KeyError:
                        pass
                    except ValueError:
                        pass
        idf = BaseTopic.id_field("users", uid)
        self.db.set_one(self.users_collection, {idf: uid}, user_data)
        if user_info.get("remove_project_role_mappings"):
            idf = "user_id" if idf == "_id" else idf
            self.db.del_list(self.tokens_collection, {idf: uid})

    def delete_user(self, user_id):
        """
        Delete user.

        :param user_id: user identifier.
        :raises AuthconnOperationException: if user deletion failed.
        """
        self.db.del_one(self.users_collection, {"_id": user_id})
        self.db.del_list(self.tokens_collection, {"user_id": user_id})
        return True

    def get_user_list(self, filter_q=None):
        """
        Get user list.

        :param filter_q: dictionary to filter user list by:
            name (username is also admitted).  If a user id is equal to the filter name, it is also provided
            other
        :return: returns a list of users.
        """
        filt = filter_q or {}
        if "name" in filt:  # backward compatibility
            filt["username"] = filt.pop("name")
        if filt.get("username") and is_valid_uuid(filt["username"]):
            # username cannot be a uuid. If this is the case, change from username to _id
            filt["_id"] = filt.pop("username")
        users = self.db.get_list(self.users_collection, filt)
        project_id_name = {}
        role_id_name = {}
        for user in users:
            prms = user.get("project_role_mappings")
            projects = user.get("projects")
            if prms:
                projects = []
                # add project_name and role_name. Generate projects for backward compatibility
                for prm in prms:
                    project_id = prm["project"]
                    if project_id not in project_id_name:
                        pr = self.db.get_one(
                            self.projects_collection,
                            {BaseTopic.id_field("projects", project_id): project_id},
                            fail_on_empty=False,
                        )
                        project_id_name[project_id] = pr["name"] if pr else None
                    prm["project_name"] = project_id_name[project_id]
                    if prm["project_name"] not in projects:
                        projects.append(prm["project_name"])

                    role_id = prm["role"]
                    if role_id not in role_id_name:
                        role = self.db.get_one(
                            self.roles_collection,
                            {BaseTopic.id_field("roles", role_id): role_id},
                            fail_on_empty=False,
                        )
                        role_id_name[role_id] = role["name"] if role else None
                    prm["role_name"] = role_id_name[role_id]
                user["projects"] = projects  # for backward compatibility
            elif projects:
                # user created with an old version. Create a project_role mapping with role project_admin
                user["project_role_mappings"] = []
                role = self.db.get_one(
                    self.roles_collection,
                    {BaseTopic.id_field("roles", "project_admin"): "project_admin"},
                )
                for p_id_name in projects:
                    pr = self.db.get_one(
                        self.projects_collection,
                        {BaseTopic.id_field("projects", p_id_name): p_id_name},
                    )
                    prm = {
                        "project": pr["_id"],
                        "project_name": pr["name"],
                        "role_name": "project_admin",
                        "role": role["_id"],
                    }
                    user["project_role_mappings"].append(prm)
            else:
                user["projects"] = []
                user["project_role_mappings"] = []

        return users

    def get_project_list(self, filter_q={}):
        """
        Get role list.

        :return: returns the list of projects.
        """
        return self.db.get_list(self.projects_collection, filter_q)

    def create_project(self, project_info):
        """
        Create a project.

        :param project: full project info.
        :return: the internal id of the created project
        :raises AuthconnOperationException: if project creation failed.
        """
        pid = self.db.create(self.projects_collection, project_info)
        return pid

    def delete_project(self, project_id):
        """
        Delete a project.

        :param project_id: project identifier.
        :raises AuthconnOperationException: if project deletion failed.
        """
        idf = BaseTopic.id_field("projects", project_id)
        r = self.db.del_one(self.projects_collection, {idf: project_id})
        idf = "project_id" if idf == "_id" else "project_name"
        self.db.del_list(self.tokens_collection, {idf: project_id})
        return r

    def update_project(self, project_id, project_info):
        """
        Change the name of a project

        :param project_id: project to be changed
        :param project_info: full project info
        :return: None
        :raises AuthconnOperationException: if project update failed.
        """
        self.db.set_one(
            self.projects_collection,
            {BaseTopic.id_field("projects", project_id): project_id},
            project_info,
        )
