#!/usr/bin/python3
import zlib
from main import *
from adventurers import *
from flask import Flask, render_template, redirect, request, make_response
from flask_session import Session

app = Flask(__name__)

# useful functions
def compress_character(adventurer):
    cookie_string = adventurer.identifier
    adventurer_json = json.dumps(adventurer.get_json())
    compressed_data = zlib.compress(adventurer_json.encode())
    cookie_data = base64.urlsafe_b64encode(compressed_data).decode()
    return cookie_string, cookie_data

def return_character_from_cookie(cookie):
    cookie_decompressed = base64.urlsafe_b64decode(cookie)
    adventurer_dict = json.loads(zlib.decompress(cookie_decompressed).decode())
    adventurer = AdventurerGen.create_from_dict(adventurer_dict)
    return adventurer

@app.route('/')
def index():
    tab = request.args.get("tab", default="what", type=str)
    # control argument inputs to tabs available on index.html
    if tab not in [ "what", "how", "why", "about" ]:
        tab = "what"
    return render_template("index.html", tab=tab)

@app.route('/party', methods = ["GET"])
def party():
    # default values, modified if cookies exist
    stored_adv_party = []
    stored_count = None
    stored_level = None
    if request.method == "GET":
        count = request.args.get("count", default=4, type=int)
        level = request.args.get("level", default=1, type=int)
        cache = request.args.get("cache", default='true', type=str)
        # control inputs to prevent abuse
        if cache not in [ "true", "false" ]:
            cache = 'true'
        if level < 1 or level > 5:
            level = 1
        if count < 2 or count > 5:
            count = 4
        # generate an adventuring party
        adv_party = PartyGen.get_new_party(count, level) 
        # check for cookies present
        if request.cookies:
            stored_count = len(request.cookies)
            for c in request.cookies:
                if c.startswith('adv'):
                    new_char = return_character_from_cookie(request.cookies[c])
                    stored_level = new_char.level
                    stored_adv_party.append(new_char)
            # if request arguments match the adventure party count & level stored in the cookies, just use the cookies
            if cache == 'true':
                if level != stored_level:
                    for adv in stored_adv_party:
                        adv.set_level(level)
                if count == stored_count:
                    adv_party.set_party(stored_adv_party, count, level)
                if count > stored_count:
                    extension = count - stored_count
                    more_party_members = PartyGen.get_new_party(extension,level).adventurers
                    extended_party = stored_adv_party + more_party_members
                    adv_party.set_party(extended_party, count, level)
                if count < stored_count:
                    reduction = count - stored_count
                    reduced_party = stored_adv_party[:reduction]
                    adv_party.set_party(reduced_party, count, level)
        # generate page
        response = make_response(render_template("party.html", adv_party=adv_party, count=count, level=level, cache=cache))
        # make a cookie for each character
        for adv in adv_party.adventurers:
            cookie_string, cookie_data = compress_character(adv)
            response.set_cookie(cookie_string, cookie_data)
        return response

@app.route('/character', methods = ["GET","POST"])
def character():
    if request.method == "GET":
        c_id = request.args.get("id", default="adv-1", type=str)
        level = request.args.get("level", default=1, type=int)
        role = request.args.get("role", default="fighter", type=str)
        cache = request.args.get("cache", default='true', type=str)
        if cache not in [ "true", "false" ]:
            cache = 'true'
        if not c_id.startswith('adv-'):
            c_id = 'adv-1'
        if level < 1 or level > 5:
            level = 1
        if role not in [ 'fighter','magic-user','cleric', 'thief', 'dwarf', 'elf', 'halfling']:
            role = 'fighter'
        if request.cookies and cache != "false":
            character = return_character_from_cookie(request.cookies[c_id])
            print(character.player_class)
            if character.level != level:
                character.set_level(level)
            # reroll until we get our class
            while character.player_class != role.replace("-"," "):
                new_char = Adventurer(c_id, level)
                selected_class = AdventurerGen(new_char).selection()
                character = selected_class(new_char.identifier, new_char.level, new_char.get_attributes())
        else:
            new_char = Adventurer(c_id, level)
            selected_class = AdventurerGen(new_char).selection()
            character = selected_class(new_char.identifier, new_char.level, new_char.get_attributes())
            role = character.player_class
            level = character.level
        response = make_response(render_template("character.html", character=character, level=level, cache=cache,role=role))
        cookie_string, cookie_data = compress_character(character)
        response.set_cookie(cookie_string, cookie_data)
    return response
