# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 Avencall
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>

from contextlib import contextmanager
from functools import wraps
import logging

import requests
from flask import current_app
from flask import redirect
from flask import request
from flask import url_for
from werkzeug.local import LocalProxy

from xivo_auth_client.client import AuthClient

logger = logging.getLogger(__name__)
current_user = LocalProxy(lambda: get_user())


@contextmanager
def xivo_auth(config):
    yield AuthClient(**config)

def new_auth_client(config):
    return AuthClient(**config)

def required_acl(acl):
    def wrapper(func):
        func.acl = acl
        return func
    return wrapper

def verify_token(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        token = request.cookies.get('x-auth-session', '')
        token_is_valid = None

        if token:
            try:
                with xivo_auth(current_app.config['auth']) as auth:
                    acl = getattr(func, 'acl', '')
                    token_is_valid = auth.token.is_valid(token, acl.format(**kwargs))
            except requests.RequestException as e:
                auth_host = current_app.config['auth']['host']
                auth_port = current_app.config['auth']['port']
                message = 'Could not connect to authentication server on {host}:{port}: {error}'.format(host=auth_host, port=auth_port, error=e)
                logger.exception(message)

            if token_is_valid:
                return func(*args, **kwargs)

        response = redirect(url_for('login_admin.LoginAdmin:get'))
        response.set_cookie('x-auth-session', '', expires=0)

        if current_app.config['webi']['enable']:
            response.set_cookie('_eid', '', expires=0)

        return response
    return wrapper

def get_user():
    return User()

class User(object):

    @property
    def is_authenticated(self):
        token = request.cookies.get('x-auth-session', '')
        with xivo_auth(current_app.config['auth']) as auth:
            token_is_valid = auth.token.is_valid(token)
            if token_is_valid:
                return True
        return False

    def get_uuid(self):
        token = request.cookies.get('x-auth-session', '')
        with xivo_auth(current_app.config['auth']) as auth:
            token = auth.token.get(token)
        return token['auth_id']
