# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2017-2018 CERN.
#
# Invenio is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.

from flask import Flask, url_for
from flask_admin import Admin
from invenio_db import db

from invenio_oauth2server import InvenioOAuth2Server
from invenio_oauth2server.admin import (
    ClientView,
    TokenView,
    oauth2server_clients_adminview,
    oauth2server_tokens_adminview,
)


def test_admin(models_fixture):
    """Test flask-admin interface."""
    app = models_fixture
    InvenioOAuth2Server(app)

    assert isinstance(oauth2server_tokens_adminview, dict)
    assert isinstance(oauth2server_clients_adminview, dict)

    assert "view_class" in oauth2server_tokens_adminview
    assert "view_class" in oauth2server_clients_adminview

    admin = Admin(app, name="Test")

    clients_view = oauth2server_clients_adminview.pop("view_class")
    clients_model, clients_session = oauth2server_clients_adminview.pop("args")
    clients_kwargs = oauth2server_clients_adminview.pop("kwargs")
    tokens_view = oauth2server_tokens_adminview.pop("view_class")
    tokens_model, tokens_session = oauth2server_tokens_adminview.pop("args")
    tokens_kwargs = oauth2server_tokens_adminview.pop("kwargs")
    admin.add_view(clients_view(clients_model, db.session, **clients_kwargs))
    admin.add_view(tokens_view(tokens_model, db.session, **tokens_kwargs))

    menu_items = {str(item.name): item for item in admin.menu()}
    assert "User Management" in menu_items
    assert menu_items["User Management"].is_category()

    submenu_items = {
        str(item.name): item for item in menu_items["User Management"].get_children()
    }
    assert "OAuth Applications" in submenu_items
    assert "OAuth Application Tokens" in submenu_items

    with app.test_request_context():
        token_request_url = url_for("token.index_view")
        client_request_url = url_for("client.index_view")
        client_view_url = url_for(
            "invenio_oauth2server_settings.client_view", client_id="client_test_u1c1"
        )
        client_reset_url = url_for(
            "invenio_oauth2server_settings.client_reset", client_id="client_test_u1c1"
        )
        token_view_url = url_for(
            "invenio_oauth2server_settings.token_view", token_id="1"
        )
        token_revoke_url = url_for(
            "invenio_oauth2server_settings.token_revoke", token_id="1"
        )

    with app.app_context():
        with app.test_client() as client:
            res = client.get(token_request_url, follow_redirects=True)
            assert res.status_code == 200
            res = client.get(client_request_url, follow_redirects=True)
            assert res.status_code == 200
            res = client.get(client_view_url, follow_redirects=True)
            assert res.status_code == 200
            res = client.post(client_reset_url, follow_redirects=True)
            assert res.status_code == 200
            res = client.get(token_view_url, follow_redirects=True)
            assert res.status_code == 200
            res = client.post(token_revoke_url, follow_redirects=True)
            assert res.status_code == 405
