from flask import session, Flask, abort, render_template, flash, redirect
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms.ext.sqlalchemy.orm import model_form
import os
from wtforms import StringField, PasswordField, validators
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = 'postgresql:///goopher'
db = SQLAlchemy(app)
app.secret_key=os.urandom(32)

class Juoni(db.Model):
	id = db.Column(db.Integer, primary_key=True)
	text = db.Column(db.String(160), nullable=False)
	name = db.Column(db.String, nullable=False)

class User(db.Model):
	id = db.Column(db.Integer, primary_key=True)
	email = db.Column(db.String, nullable=False)
	passwordHash = db.Column(db.String, nullable=False)

	def setPassword(self, password):
		self.passwordHash = generate_password_hash(password)

	def checkPassword(self, password):
		return check_password_hash(self.passwordHash, password)

JuoniForm = model_form(model=Juoni, base_class=FlaskForm, db_session=db.session)

class UserForm(FlaskForm):
	email = StringField("email", validators=[validators.Email()])
	password = PasswordField("password",
	validators=[validators.InputRequired()])

class RegisterForm(UserForm):
	key = StringField("registration key",
	validators=[validators.InputRequired()])

@app.before_first_request
def juonet():
	db.create_all()

	juoni = Juoni(text="Lasse leijjona leikii piilosta mutta hänen ystävä pate eksyy. se löytyy", name="lasse leijjona")
	db.session.add(juoni)

	juoni = Juoni(text="Pate porsas leikii hipaa mutta hänen ystävä joonas eksyy. se löytyy", name="harmillinen hippa")
	db.session.add(juoni)

	user = User(email="wall@potato.dog")
	user.setPassword("cat")
	db.session.add(user)

	db.session.commit()

@app.route("/<int:id>/edit", methods=["GET", "POST"])
@app.route("/new", methods=["GET", "POST"])
def lomake(id=None):
	loginRequired()
	juoni = Juoni()
	if id:
		juoni = Juoni.query.get_or_404(id)
	form = JuoniForm(obj=juoni)
	if form.validate_on_submit():
		form.populate_obj(juoni)
		db.session.add(juoni)
		db.session.commit()
		flash("Added")
		return redirect("/")
		print("Added your juoni, thanks.")
	return render_template("new.html", form=form)

@app.route("/<int:id>/delete")
def deletejuoni(id):
	juoni = Juoni.query.get_or_404(id)
	db.session.delete(juoni)
	db.session.commit()
	flash("Deleted.")
	return redirect("/")

@app.route("/")
def index():
	juonis = Juoni.query.all()
	return render_template("index.html", juonis=juonis)

def currentUser():
	try:
		uid = int(session["uid"])
	except:
		return None

	return User.query.get(uid)

app.jinja_env.globals["currentUser"] = currentUser

def loginRequired():
	print("loginRequired")
	if not currentUser():
		abort(403)

@app.route("/login", methods=["GET", "POST"])
def loginView():
	form = UserForm()
	if form.validate_on_submit():
		email = form.email.data
		password = form.password.data
		user = User.query.filter_by(email=email).first()

		if not user:
			flash("Bad username or password.")
			print("No such user")
			return redirect("/login")

		if not user.checkPassword(password):
			flash("Bad username or password.")
			print("Bad password")
			return redirect("/login")
		flash("Logged in. Welcome!")
		session["uid"]=user.id
		return redirect("/")

	return render_template("login.html", form=form)

@app.route("/register", methods=["GET", "POST"])
def registerView():
	form = RegisterForm()
	if form.validate_on_submit():
		if form.key.data != "peruna":
			flash("Bad registration key.")
			return redirect("/register")
		user = User()
		user.email = form.email.data
		user.setPassword(form.password.data)
		db.session.add(user)
		db.session.commit()
		flash("User created. Now, log in!")
		return redirect("/login")
	return render_template("register.html", form=form)

@app.route("/logout")
def logoutView():
	session["uid"]=None
	return redirect("/")

if __name__ == "__main__":
	app.run()
