__author__ = 'croxis'
from datetime import datetime
from io import BytesIO
import os
from queue import Empty
import random
from subprocess import PIPE
import time
import urllib.parse
import zipfile

import eventlet
from eventlet import Queue
from eventlet.green.subprocess import Popen

from flask import make_response, redirect, render_template, send_file, session, \
    url_for
from flask.ext.socketio import join_room, leave_room
import lib.cardlib as cardlib
import lib.utils as utils
from reportlab.lib.pagesizes import landscape, letter
from reportlab.lib.utils import ImageReader

from . import main
from ..card_visual import create_card_img
from .. import app, session_manager, socketio
from .forms import GenerateCardsForm, MoreOptionsForm, SubmitCardsForm, \
    get_checkpoints_options

thread_pool = {}  # CERF token: thread


def enqueue_output(process, queue):
    while process.poll() is None:
        try:
            line = process.stdout.readline().decode() #  Remove decode with unl
            if line.count('|') >= 9:
                app.logger.debug("Line: " + line)
                queue.put(line)
            time.sleep(0.1)
        except ValueError:
            time.sleep(0.1)


@main.route('/')
def index():
    return redirect(url_for('.index_mtgai'))


@main.route('/mtgai', methods=['GET', 'POST'])
def index_mtgai():
    random_form = GenerateCardsForm()
    random_form.checkpoint.choices = get_checkpoints_options()
    form = SubmitCardsForm()
    if random_form.validate_on_submit():
        session['render_mode'] = random_form.render_mode.data
        session['checkpoint_path'] = random_form.checkpoint.data
        session['seed'] = random_form.seed.data
        session['primetext'] = random_form.primetext.data
        session['length'] = random_form.length.data
        session['temperature'] = float(random_form.temperature.data)
        session['name'] = random_form.name.data.lower()  # Uppercase crashes nn
        session['supertypes'] = random_form.supertypes.data
        session['types'] = random_form.types.data
        session['subtypes'] = random_form.subtypes.data
        session['rarity'] = random_form.rarity.data
        session['bodytext_prepend'] = random_form.bodytext_prepend.data
        session['bodytext_append'] = random_form.bodytext_append.data
        return redirect(url_for('.card_select'))
    if form.validate_on_submit():
        session['cardtext'] = form.body.data
        session['cardsep'] = '\r\n\r\n'
        session['mode'] = "existing"
        session['render_mode'] = form.render_mode.data
        session['checkpoint_path'] = ''
        return redirect(url_for('.card_select'))
    random_form.seed.data = random.randint(0, 255)
    return render_template('index.html',
                           current_time=datetime.utcnow(),
                           form=form,
                           random_form=random_form,
                           name='name',
                           title='MTG Automatic Inventor (MTGAI)')


@socketio.on('generate')
def card_generate():
    # Filebased systems need the session cleaned up manually
    session_manager.cleanup_sessions()
    checkpoint_option = session['checkpoint_path']
    do_nn = checkpoint_option != "None"
    if do_nn:
        checkpoint_path = os.path.join(
            os.path.expanduser(app.config['SNAPSHOTS_PATH']),
            checkpoint_option)
    length = int(session['length'])
    if length > app.config['LENGTH_LIMIT']:
        length = app.config['LENGTH_LIMIT']
    socketio.emit('set max char', {'data': length})
    length += 140  # Small fudge factor to be a little more accurate with
    # the amount of text actually generated
    use_render_mode(session["render_mode"])
    if do_nn:
        command = ['th', 'sample_hs_v3.1.lua', checkpoint_path, '-gpuid',
                   str(app.config['GPU'])]
    else:
        command = ['-gpuid', str(app.config['GPU'])]
    if session['seed']:
        command += ['-seed', str(session['seed'])]
    if session['primetext']:
        command += ['-primetext', session['primetext']]
    if session['length']:
        command += ['-length', str(length)]
    if session['temperature']: