#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Jun 29 11:44:26 2019

@author: LeoH
"""
import random
import os
import io
import altair as alt
import pandas as pd
from pymongo import MongoClient
from flask import Flask, render_template, send_file, abort, request, redirect
from populate_mongodb import Populator
from os import path

app = Flask(__name__)
#We need to set auto_reload and TEMPLATES_AUTO_RELOAD because
# we generate html files in templates folder
app.jinja_env.auto_reload = True
app.config['TEMPLATES_AUTO_RELOAD'] = True

client = MongoClient(
    os.environ['DB_PORT_27017_TCP_ADDR'],
    27017)
db = client.quicksign

@app.route('/')
def hello_world():
    return render_template("home.html")

@app.route('/image/<MD5>')
def getmd5(MD5):
    """
    Display image if stored in collection
    or return an error 404 if not
    :param MD5: string
    :return: <front image>
    """
    item = db.collection_image.find_one({'md5': MD5})
    if item is None:
        abort(404, description="Resource not found, please use another MD5")
    byte = io.BytesIO(item['img_grey'])
    return send_file(byte,
                     attachment_filename=MD5,
                     mimetype='image/png')

@app.route('/randomimage')
def getrandommd5():
    """
    Display a random image stored in collection
    or return an error 404 if no image in collection
    :param MD5: string
    :return: <front image>
    """
    count = db.collection_image.count()
    if count == 0:
        render_template("home.html", info='No image to display !')
    item = db.collection_image.find()[random.randrange(count)]
    byte = io.BytesIO(item['img_grey'])
    app.logger.info(f'Displaying MD5 : {item["md5"]}')

    return send_file(byte,
                     attachment_filename=item['md5'],
                     mimetype='image/png')

@app.route('/monitoring')
def monitoring():
    """
    Combine html generated by generate_graph
    And dataframe used to generate the graph
    If mongodb collection is empty, df is None
    :return: <front parent_monitoring>
    """
    df = generate_graph()
    if df is None:
        return render_template("home.html", info='Please populate Mongodb !')
    else:
        df['time'] = df.datetime_created.dt.strftime('%Y-%m-%d-%H-%M')
        stats = df.groupby(['time', 'error']).datetime_created.count().reset_index()
        stats.rename({'datetime_created': 'count'}, inplace=True)
        return render_template("parent_monitoring.html",
                               tables=[stats.to_html(classes='data')],
                               titles=stats.columns.values)

@app.route('/testmonitoring')
def test_monitoring():
    """
    display graph generated by generate_graph
    :return: <front monitor>
    """
    return render_template("monitor.html")

@app.route('/result', methods=['POST', 'GET'])
def populate():
    """
    Try to populate hive
    Else:
    Redirect to the right page with error message
    :return: <front monitoring> / <front home>
    """
    if request.method == 'POST':
        result = request.form
    else:
        return redirect("/monitoring")
    if path.exists(result['path']):
        if Populator(app, db, result['path']).populatemongo():
            return render_template("home.html", info='Already populating please wait')

        return redirect("/monitoring")
    else:
        return render_template("home.html", info="file don't exist, try another path !")

def generate_graph():
    """
    Generate an html page with altair
    If mongodb collection is empty, return None
    :return: <class 'pandas.core.frame.DataFrame'>
    """
    li = []
    cursor = db.collection_image_status.find()
    for document in cursor:
        li.append({'error': document['error'],
                   'datetime_created': document['datetime_created']
                   })
    df = None
    if len(li) != 0:
        df = pd.DataFrame(li)
        chart = alt.Chart(df).mark_area(
            interpolate='step').encode(
            x='hoursminutes(datetime_created):O',
            y='count(error)',
            color='error'
        )
        chart.save('templates/monitor.html')
    else:
        app.logger.info('No data in mongodb')
    return df

if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=True)