from os import urandom, getenv

from flask import Flask, render_template, request, session, url_for

from model import init_db
from user_ops import UserOps
from exceptions import InvalidCredentialsError, UserExistsError

BASEURL = getenv('BASEURL', '')
init_db()
app = Flask(__name__)
app.secret_key = urandom(32)
app.jinja_env.globals.update(get_url=lambda endpoint: f'{BASEURL}{url_for(endpoint)}') # pylint: disable=no-member


@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        try:
            UserOps(request.form.get('username'),
                    request.form.get('password')).authenticate()
        except InvalidCredentialsError:
            return render_template('login.html', alert='Invalid credentials!')

        session['logged_in'] = True
        session['username'] = request.form['username']
        return render_template('internal.html')
    
    if session.get('logged_in'):
        return render_template('internal.html')
    return render_template('login.html')


@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        if not all([request.form.get('username'),
                    request.form.get('password'),
                    request.form.get('passwordconfirm')]):
            return render_template('register.html', alert='You need to fill everything.')
        if request.form['password'] != request.form['passwordconfirm']:
            return render_template('register.html', alert='Passwords do not match! Please try again.')

        try:
            UserOps(request.form.get('username'),
                    request.form.get('password')).register()
        except UserExistsError:
            return render_template('register.html', alert='Username already in use.')

        return render_template('login.html', success=('Account "{}" successfully registered. '
                                                      'You can log in now!'.format(request.form['username'])))

    return render_template('register.html')


@app.route('/logout')
def logout():
    try:
        session.pop('logged_in')
        session.pop('username')
    except KeyError:
        pass
    return render_template('login.html')


@app.errorhandler(401)
@app.errorhandler(404)
@app.route('/error')
def error(error):
    return render_template('error.html', error=error), error.code


# 500 needs a separate handler, as Flask would print
# the actual piece of code that caused the exception
# for some bizarre reason
@app.errorhandler(500)
@app.route('/error')
def servererror(error):
    return render_template('error.html', error='500: Internal server error'), 500


if __name__ == '__main__':
    app.run(host='127.0.0.1', debug=False, port=11111)