import json
import os
from functools import wraps

import click
from flask import Flask, jsonify, render_template
from flask_simplelogin import SimpleLogin, login_required
from import check_password_hash, generate_password_hash

# [ -- Utils -- ]

def validate_login(user):
    db_users = json.load(open('users.json'))
    if not db_users.get(user['username']):
        return False
    stored_password = db_users[user['username']]['password']
    if check_password_hash(stored_password, user['password']):
        return True
    return False

def create_user(**data):
    """Creates user with encrypted password"""
    if 'username' not in data or 'password' not in data:
        raise ValueError('username and password are required.')

    # Hash the user password
    data['password'] = generate_password_hash(

    # Here you insert the `data` in your users database
    # for this simple example we are recording in a json file
    db_users = json.load(open('users.json'))
    # add the new created user to json
    db_users[data['username']] = data
    # commit changes to database
    json.dump(db_users, open('users.json', 'w'))
    return data

# [--- Flask Factories  ---]

def create_app():
    app = Flask(__name__)
    return app

def configure_extensions(app):
    SimpleLogin(app, login_checker=validate_login)
    if not os.path.exists('users.json'):
        with open('users.json', 'a') as json_file:
            # This just touch create a new dbfile
            json.dump({'username': '', 'password': ''}, json_file)

def configure_views(app):
    def index():
        return render_template('index.html')

    def secret():
        return render_template('secret.html')

    @app.route('/api', methods=['POST'])
    def api():
        return jsonify(data='You are logged in with basic auth')

    def complexview():
        return render_template('secret.html')

# [--- Command line functions ---]

def with_app(f):
    """Calls function passing app as first argument"""
    def decorator(*args, **kwargs):
        app = create_app()
        return f(app=app, *args, **kwargs)
    return decorator
def main():
    """Flask Simple Login Example App"""

@click.option('--username', required=True, prompt=True)
@click.option('--password', required=True, prompt=True, hide_input=True,
def adduser(app, username, password):
    """Add new user with admin access"""
    with app.app_context():
        create_user(username=username, password=password)
        click.echo('user created!')

@click.option('--reloader/--no-reloader', default=None)
@click.option('--debug/--no-debug', default=None)
@click.option('--host', default=None)
@click.option('--port', default=None)
def runserver(app=None, reloader=None, debug=None, host=None, port=None):
    """Run the Flask development server i.e."""
    debug = debug or app.config.get('DEBUG', False)
    reloader = reloader or app.config.get('RELOADER', False)
    host = host or app.config.get('HOST', '')
    port = port or app.config.get('PORT', 5000)

# [--- Entry point ---]

if __name__ == "__main__":
    # python to see help