#!/usr/bin/python

import os, random, sys, json
from datetime import datetime
from subprocess import call

import serial
from flask import Flask, render_template, jsonify, make_response, request, redirect, url_for, abort, session, flash
from flask_limiter import Limiter
from pprint import pprint
from flask_limiter.util import get_remote_address

# Update to using the new Python 3 lib
import board
import busio

import adafruit_thermal_printer

ThermalPrinter = adafruit_thermal_printer.get_printer_class(2.69)

RX = board.RX
TX = board.TX

uart = serial.Serial("/dev/ttyAMA0", baudrate=19200, timeout=3000)
printer = ThermalPrinter(uart, auto_warm_up=False)

# Initialize the printer.  Note this will take a few seconds for the printer
# to warm up and be ready to accept commands (hence calling it explicitly vs.
# automatically in the initializer with the default auto_warm_up=True).
printer.warm_up()

if printer.has_paper():
    print('Printer has paper!')
else:
    print('Printer might be out of paper, or RX is disconnected!')



app = Flask(__name__)
app.secret_key = b'\x98>3nW[D\xa4\xd4\xd0K\xab?oM.`\x98'
limiter = Limiter(
    app,
    key_func=get_remote_address,
    default_limits=["200 per day", "50 per hour"]
)

SERIAL_PORT = '/dev/ttyAMA0'
BAUDRATE = 19200

# session['logged_in'] = False

def error_handler_limiter():
    flash("Trop de requêtes !!! CANNOT PRINT !!! HAAAAAAAAAA",'dark')
    return redirect(url_for('display_index_page'))

@app.errorhandler(418)
def i_m_a_tea_pot(error):
    return make_response('☕\n', 418)

@app.route('/tea')
def tea():
    abort(418)

@app.route('/')
@limiter.exempt
def display_index_page():
    if session.get('logged_in'):
        return render_template('index.html')
    else:
        return redirect(url_for('login'))

@app.route('/login', methods=['POST','GET'])
@limiter.limit("100 per minute", error_message=error_handler_limiter)
def login():
    if request.method == 'POST':
        if not session.get('logged_in'):
            if request.form['username'] and request.form['password']:
                # Get the json
                with open('users.json') as f:
                    users_file = json.load(f)
                for user in users_file["users"]:
                    if users_file["users"][user] == request.form['password']:
                        session['logged_in'] = True
                        session['user'] = request.form['username']

                if not session.get('logged_in'):
                    flash('Mot de passe ou pseudo invalide.','danger')
                    return redirect(url_for('login'))
                else:
                    return redirect(url_for('display_index_page'))
            else:
                flash('Incorrect logins')
                return render_template('password.html')
        else:
            return render_template('password.html')
    else:
        return render_template('password.html')

@app.route("/logout")
def logout():
    session['logged_in'] = False
    flash('Tu est déconnecté', 'info')
    return redirect(url_for('login'))

# @app.route('/print/image')
# @limiter.limit("5 per minute", error_message=error_handler_limiter)
# def print_image():
#     if session.get('logged_in'):
#         img = random.choice(os.listdir("static/images/")) #change dir name to whatever
#         # call(["lp", "-o fit-to-page", "static/images/" + img])
#         printer = Adafruit_Thermal(SERIAL_PORT, BAUDRATE, timeout=5)
#         printer.begin()
#         printer.feed(1)
#         printer.printImage("static/images/" + img, True)
#         printer.feed(2)
#         return redirect(url_for('display_index_page'))
#     else:
#         return redirect(url_for('login'))

@app.route('/print/text', methods=['POST'])
@limiter.limit("3: per minute", error_message=error_handler_limiter)
def print_text():
    if session.get('logged_in'):
        if len(request.form['message']) < 200:
            printer.set_defaults()
            printer.print((request.form['message']))
            printer.print("From" + session['user'])
            printer.feed(2)

            return redirect(url_for('display_index_page'))
        else:
            flash('Le text est trop long, 200 caractères au maximum stp !')
            return redirect(url_for('display_index_page'))
    else:
        return redirect(url_for('login'))
