"""
Security related functions including user credential authentication and JWT based authentication integration.

:copyright: Copyright 2013-2016, Dorian Pula <dorian.pula@amber-penguin-software.ca>
:license: AGPL v3+
"""

import collections
import logging

import flask
import flask_jwt
from werkzeug import security

from rookeries.users import models

Credentials = collections.namedtuple('Credentials', ['username', 'password'])
ADMIN_USERNAME = 'ADMIN_USERNAME'
ADMIN_PASSWORD = 'ADMIN_PASSWORD'

jwt = flask_jwt.JWT()


@jwt.authentication_handler
def valid_admin_user_credentials(username, password):
    """Checks if the supplied password matches the stored password hash."""
    credentials = Credentials(username, password)
    config = flask.current_app.config

    # TODO: Migrate this over into where the user is created and stored.
    stored_credentials = security.generate_password_hash(config[ADMIN_PASSWORD])

    valid_password = security.check_password_hash(stored_credentials, credentials.password)
    if credentials.username == config[ADMIN_USERNAME] and valid_password:
        logging.info('Valid user credentials for "%s"', credentials.username)
        return models.User(username=credentials.username, full_name='Admin')


@jwt.identity_handler
def load_user(payload):
    config = flask.current_app.config
    if payload['user_id'] == 1:
        logging.info('Loading superadmin user "%s"', ADMIN_USERNAME)
        return models.User(username=config[ADMIN_USERNAME], full_name='Admin')


@jwt.auth_response_handler
def jwt_token_response(access_token, identity):
    response = {
        'token': access_token.decode(encoding="utf-8"),
        'user': {
            'username': identity.username,
            'fullName': identity.full_name,
        }
    }
    return flask.jsonify(response)
