import re

from django.contrib.auth.models import User
from django.core.wsgi import get_wsgi_application
import pytest
from webtest import TestApp

from passerelle.base.models import ApiUser

pytestmark = pytest.mark.django_db

@pytest.fixture
def simple_user():
    try:
        user = User.objects.get(username='user')
    except User.DoesNotExist:
        user = User.objects.create_user('user', password='user')
    return user

@pytest.fixture
def admin_user():
    try:
        user = User.objects.get(username='admin')
    except User.DoesNotExist:
        user = User.objects.create_superuser('admin', email=None, password='admin')
    return user

def login(app, username='admin', password='admin'):
    login_page = app.get('/login/')
    login_form = login_page.forms[0]
    login_form['username'] = username
    login_form['password'] = password
    resp = login_form.submit()
    assert resp.status_int == 302
    return app

def test_homepage_redirect():
    app = TestApp(get_wsgi_application())
    assert app.get('/', status=302).location == 'http://localhost:80/manage/'

def test_unlogged_access():
    # connect while not being logged in
    app = TestApp(get_wsgi_application())
    assert app.get('/manage/', status=302).location == 'http://localhost:80/login/?next=/manage/'

def test_simple_user_access(simple_user):
    # connect while being logged as a simple user
    app = login(TestApp(get_wsgi_application()), username='user', password='user')
    assert app.get('/manage/', status=403)
    assert app.get('/manage/add', status=403)
    assert app.get('/manage/ovh/add', status=403)
    assert app.get('/manage/access/', status=403)

def test_access(admin_user):
    app = login(TestApp(get_wsgi_application()))
    resp = app.get('/manage/', status=200)
    assert 'Add Connector' in resp.body
    assert app.get('/manage/access/', status=200)

def test_add_connector(admin_user):
    app = login(TestApp(get_wsgi_application()))
    resp = app.get('/manage/', status=200)
    resp = resp.click('Add Connector')
    assert 'Business Process Connectors' in resp.body
    assert 'Geographic information system' in resp.body
    resp = resp.click('Base Adresse Web Service')
    resp.forms[0]['title'] = 'Test Connector'
    resp.forms[0]['description'] = 'Connector for a simple test'
    resp.forms[0]['service_url'] = 'https://api-adresse.data.gouv.fr/'
    resp = resp.forms[0].submit()
    assert resp.status_int == 302
    assert resp.location == 'http://localhost:80/base-adresse/test-connector/'
    resp = resp.follow()
    assert 'Base Adresse Web Service - Test Connector' in resp.body

    resp = app.get('/manage/', status=200)
    assert 'Test Connector' in resp.body

def test_visit_connectors(admin_user):
    app = login(TestApp(get_wsgi_application()))
    resp = app.get('/manage/', status=200)
    resp = resp.click('Add Connector')
    for link in re.findall('href="(/manage.*add)"', resp.body):
        resp = app.get(link, status=200)

def test_access_management(admin_user):
    assert ApiUser.objects.count() == 0
    app = login(TestApp(get_wsgi_application()))
    resp = app.get('/manage/', status=200)
    resp = resp.click('Access Management')
    resp = resp.click('Add API User')
    resp.form['username'] = 'foo'
    resp.form['fullname'] = 'Foo'
    resp = resp.form.submit().follow()
    assert ApiUser.objects.count() == 1
    assert ApiUser.objects.get(username='foo').fullname == 'Foo'

    resp = resp.click('Add API User')
    resp.form['username'] = 'bar'
    resp.form['fullname'] = 'Bar'
    resp.form['keytype'] = 'API'
    resp = resp.form.submit()
    assert 'Key can not be empty' in resp.body

def test_menu_json(app, admin_user):
    app.get('/manage/menu.json', status=302)

    app = login(app)
    resp = app.get('/manage/menu.json')
    assert resp.headers['content-type'] == 'application/json'
    assert resp.json[0]['label'] == 'Web Services'

    resp = app.get('/manage/menu.json?callback=FooBar')
    assert resp.headers['content-type'] == 'application/javascript'
    assert resp.content.startswith('FooBar([{"')
