import os
import flask
from flask_sqlalchemy import SQLAlchemy



# TODO :
# https://www.digitalocean.com/community/tutorials/how-to-add-authentication-to-your-app-with-flask-login-fr
# https://flask-login.readthedocs.io/en/latest/#your-user-class

# puisque app routes et fonctions associees ont le meme noms, tout definir dans un fichier a part

# image entiere quand click dessus ou hover
# click sur auteur des posts ==> profile

# <!-- dont forget to supress any code from user comments -->

# gallerie
# recherche
# finir graphes

###################### end of imports ##############################################################

project_dir = os.path.dirname(os.path.abspath(__file__))
#sqlite:/// prefix to tell SQLAlchemy which database engine we're using.
DB_FILENAME = "allobjs_database.db"
database_file = "sqlite:///{}".format(os.path.join(project_dir, DB_FILENAME))

app = flask.Flask(__name__)
app.config['SECRET_KEY'] = 'dev'
app.config["SQLALCHEMY_DATABASE_URI"] = database_file
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

db = SQLAlchemy(app)

from user import User, db, fake_registers, fake_links_elo
from post import Post
from comment import Comment
import fake

###################### end of initialization #######################################################


@app.route('/register_page', methods=('GET', 'POST'))
def register_page():
    return flask.render_template("register_page.html")

@app.route('/register', methods=('GET', 'POST'))
def register():
    if flask.request.form: #check if someone just submitted the form.
        username = flask.request.form['username']
        password = flask.request.form['password']
        error = User.register(username, password)
    if error is None:
        flask.flash("Authentication successfully completed. You can log in now.")
        return flask.redirect(flask.url_for("login_page"))
    else:
        flask.flash("Authentication failed : " + error)
        return flask.redirect(flask.url_for("register_page"))

@app.route("/")
@app.route("/home")
def home():
    users = User.query.all()
    return flask.render_template("home.html", users=users) #return smth rendered with jinja


@app.route("/newpost")
def newpost():
    return flask.render_template("newpost.html", user=flask.g.user) #return smth rendered with jinja

@app.route("/show_user", methods=('GET', 'POST'))
def show_user():
    # newtitle = flask.request.form.get("newtitle")
    # oldtitle = flask.request.form.get("oldtitle")
    # book = Book.query.filter_by(title=oldtitle).first()
    # book.title = newtitle
    # db.session.commit()
    return "L'id de l'utilisateur est " + flask.request.form.get("id")
    # return flask.redirect("/") #return to home

@app.route('/found')
def found():
    username = flask.request.args.get('username')
    u = User.query.filter_by(username=username).first()
    if u:
        return flask.render_template("found.html", user=u)
    else:
        return "No user named " + username + " was found"

@app.route('/login_page', methods=('GET', 'POST'))
def login_page():
    return flask.render_template("login_page.html")

@app.route('/login', methods=('GET', 'POST'))
def login():
    if flask.request.method == 'POST':
        username = flask.request.form['username']
        password = flask.request.form['password']
        error, user = User.try_login(username, password)
        if error is None:
            flask.session.clear()
            flask.session['user_id'] = user.id
            flask.flash("Successfully logged in as " + user.username)
            return flask.redirect(flask.url_for("home"))
            # return flask.redirect("/")
        else:
            flask.flash("Log in failed : " + error)
            return flask.redirect(flask.url_for("login_page"))
    return error

@app.route('/logout', methods=('GET', 'POST'))
def logout():
    flask.session.clear()
    flask.flash("You successfully logged out")
    return flask.redirect(flask.url_for("home"))

#we need this because g.user is flushed at each request (and this is stupid but not my bad)
@app.before_request
def load_logged_in_user():
    user_id = flask.session.get('user_id')
    if user_id is None:
        flask.g.user = None
    else:
        flask.g.user = User.query.filter_by(id=int(user_id)).first()
        print("loaded logged user : ", flask.g.user)

###################### end of routes definition ####################################################

if __name__ == "__main__":
    import sys
    if len(sys.argv) > 1 and sys.argv[1] == "reset":
        CREATE_DATABASE = True
        RESET_USERS = True
        RESET_POSTS = True
        RAND_USERS = True
        RAND_CONNEXIONS = True
        RAND_COMMENTS = True
        RAND_POSTS = True
        RAND_ANSWERS = True
        DEBUG = False
    else:
        CREATE_DATABASE = False
        RESET_USERS = False
        RESET_POSTS = False
        RAND_USERS = False
        RAND_CONNEXIONS = False
        RAND_COMMENTS = False
        RAND_POSTS = False
        RAND_ANSWERS = False
        DEBUG = True


    with app.app_context():
        if CREATE_DATABASE:
            try:
                os.remove(DB_FILENAME)
            except FileNotFoundError:
                print("Creating new db file")
            db.create_all()
        if RESET_USERS:
            User.query.delete()
        if RESET_POSTS:
            Post.query.delete()
        if RAND_USERS:
            fake_registers(10)
        if RAND_CONNEXIONS:
            User.query.get(1).score = 1000 #other have 500
            db.session.commit()
            fake_links_elo(40)
        if RAND_POSTS:
            for i in range(50):
                fake.fake_post() #depth 0
        if RAND_COMMENTS:
            for i in range(50):
                fake.fake_comment() #depth 1
        if RAND_ANSWERS:
            for i in range(50):
                fake.fake_answer() #depth 2
        # p = User.query.filter_by(username="Jean Le Bon").first()
        for u in User.query.all():
            for c in u.connexions:
                assert u in c.connexions
            for p in u.posts:
                assert p.user is u
                for comment in p.comments:
                    assert comment.parent is p
        print(sum([len(u.posts) for u in User.query.all()]), " posts")
    app.run(host='0.0.0.0', debug=DEBUG)
