# coding=utf-8
""""""
from __future__ import absolute_import, division, print_function, \
    unicode_literals

from flask_login import current_user, login_user
from pytest import fixture

from abilian.app import Application as BaseApplication
from abilian.core.models.subjects import User
from abilian.services import get_service

from .models import UserPreference
from .panel import PreferencePanel
from .service import PreferenceService


class VisiblePanel(PreferencePanel):
    id = label = "visible"

    def is_accessible(self):
        return True

    def get(self):
        return "Visible"


class AdminPanel(PreferencePanel):
    id = label = "admin"

    def is_accessible(self):
        security = get_service("security")
        return security.has_role(current_user, "admin")

    def get(self):
        return "Admin"


class Application(BaseApplication):
    def init_extensions(self):
        super(Application, self).init_extensions()
        prefs = self.services["preferences"]
        prefs.app_state.panels = []
        prefs.register_panel(VisiblePanel(), self)
        prefs.register_panel(AdminPanel(), self)


@fixture
def app(config):
    return Application(config=config)


def test_preferences(app, session):
    user = User(email="test@example.com")
    assert UserPreference.query.all() == []

    preference_service = PreferenceService()

    preferences = preference_service.get_preferences(user)
    assert preferences == {}

    preference_service.set_preferences(user, digest="daily")
    session.flush()

    preferences = preference_service.get_preferences(user)
    assert preferences == {"digest": "daily"}

    preference_service.clear_preferences(user)
    session.flush()

    preferences = preference_service.get_preferences(user)
    assert preferences == {}
    assert UserPreference.query.all() == []


def test_preferences_with_various_types(app, session):
    user = User(email="test@example.com")
    preference_service = PreferenceService()

    preference_service.set_preferences(user, some_int=1)
    session.flush()
    preferences = preference_service.get_preferences(user)
    assert preferences == {"some_int": 1}

    preference_service.set_preferences(user, some_bool=True)
    session.flush()
    preferences = preference_service.get_preferences(user)
    assert preferences == {"some_int": 1, "some_bool": True}


def test_visible_panels(app, db):
    user = User(email="test@example.com")
    security = app.services["security"]

    with app.test_request_context():
        security.start()
        login_user(user)

        for cp in app.template_context_processors["preferences"]:
            ctx = cp()
            if "menu" in ctx:
                break

        expected = ["preferences.visible"]
        assert [p["endpoint"] for p in ctx["menu"]] == expected

        security.grant_role(user, "admin")
        ctx = cp()
        expected = ["preferences.visible", "preferences.admin"]
        assert [p["endpoint"] for p in ctx["menu"]] == expected
