# -*- coding: utf-8 -*-
from mock import patch
from unittest import TestCase

from flask import Flask
from flask_api_auth import Authentication

from ..utils import get_stored_user, get_stored_role

app = Flask(__name__)
app.config['APIUSER_MANAGER'] = 'flask_api_auth.managers.BaseManager'
app.config['ROLE_MANAGER'] = 'flask_api_auth.managers.BaseManager'
app.config['API_AUTH_ADMIN_ROLE'] = 'INTERNAL/jedi'
Authentication(app)


class BaseResourceTestCase(TestCase):
    def setUp(self):
        self.maxDiff = None
        self.context = app
        self.context.config['DEBUG'] = True
        self.context.config['TESTING'] = True
        self.app = app.test_client()


class AuthResourceTestCaseMixin(object):
    test_user = None

    @property
    def current_user(self):
        return get_stored_user(self.test_user)

    def get_auth_headers(self, auth_headers):
        return {
            'ApiAuth-ApiUser': auth_headers.get(
                "ApiAuth-ApiUser",
                self.current_user.data['name'],
            ),
            'ApiAuth-ApiKey': auth_headers.get(
                'ApiAuth-ApiKey',
                self.current_user.data['key'],
            ),
            'ApiAuth-Referer': auth_headers.get(
                'ApiAuth-Referer',
                '',
            ),
        }

    def with_auth(self, method, url, auth_headers=None, **kwargs):
        if auth_headers is None:
            auth_headers = {}
        app_method = getattr(self.app, method)
        auth_headers = self.get_auth_headers(auth_headers)
        return app_method(
            url,
            headers=auth_headers,
            **kwargs
        )

    def patch_requires_auth_decorator(self):
        """Call during setUp()"""
        apiuser_deco_patcher = patch('flask_api_auth.decorators.APIUser')
        apirole_deco_patcher = patch('flask_api_auth.decorators.APIRole')

        self.addCleanup(apiuser_deco_patcher.stop)
        self.addCleanup(apirole_deco_patcher.stop)

        self.apiuser_deco_mock = apiuser_deco_patcher.start()
        self.apirole_deco_mock = apirole_deco_patcher.start()

        self.apiuser_deco_mock.manager.get.return_value = self.current_user
        self.apirole_deco_mock.manager.get.side_effect = get_stored_role


class ResourceTestCase(AuthResourceTestCaseMixin, BaseResourceTestCase):
    def setUp(self):
        super(ResourceTestCase, self).setUp()
        self.patch_requires_auth_decorator()
