import flask
import flask_wtf
import wtforms
from functools import reduce

app = flask.Flask(__name__)

# import views to route them
import webapp.views

from webapp import validation, pools, config

if hasattr(config, "secret_key"):
    app.secret_key = config.secret_key

if hasattr(config, "debug"):
    app.debug = config.debug


@app.context_processor
def inject_readable():
    return dict(readable_names=config.readable_names)

@app.context_processor
def inject_hackerspace_name():
    return dict(hackerspace_name=config.hackerspace_name)

@app.template_filter('first')
def ldap_first(v):
    return v and v[0]

@app.template_filter('readable')
def readable_tf(n):
    return config.readable_names.get(n, n)

def initialize_forms():
    forms = {}
    for f in reduce(lambda a,b: a | b, config.can.values()):
        cls, attrs = config.fields.get(f, config.default_field)
        class AddForm(flask_wtf.FlaskForm):
            value = cls(label=config.readable_names.get(f), **attrs)
        AddForm.__name__ == 'Add' + f
        forms[f] = AddForm
    return forms

@app.before_first_request
def start(*a, **kw):
    validation.sanitize_perms()
    validation.sanitize_readable()

    app.connections = pools.LDAPConnectionPool(config.ldap_url, timeout=300.0)
    def drop_profile(dn):
        if dn != config.admin_dn:
            del app.profiles[dn]
    app.connections.register_callback('drop', drop_profile)
    app.connections.start()

    app.tokens = pools.TokenPool(timeout=600.0)
    app.tokens.start()

    app.profiles = {}
    app.forms = initialize_forms()

