import hashlib
import datetime
import os
import random
from google.appengine.ext import db
from string import letters
import constants
import models
from constants import messageDict

def render_str(template, **params):
    if params.has_key('lang'):
        if not params['lang'] in constants.languages:
            params['lang'] = 'en'
        template = params['lang'] + '/' + template
        
    t = constants.jinjaenv.get_template(template)
    return t.render(params)
    
def securify_cookie(s):
    s = str(s)
    return s + '|' + hashlib.sha256(s + constants.COOKIESECRET).hexdigest()
    
def verify_cookie(s):
    #logging.error('cookie string is %s' % s)
    if not s:
        return None
    value, vhash = s.split('|')
    if s == securify_cookie(value):
        return value
    else:
        return None
        
def securify_password(username, password, salt = None):
    if not salt:
        salt = ''.join([random.choice(letters) for i in range(5)])
    return hashlib.sha256(username + password + salt).hexdigest() + '|' + salt
    
def verify_password(username, password, hashedpw):
    [pw, salt] = hashedpw.split('|')
    return securify_password(username, password, salt) == hashedpw
    
def validate_user(userid):
    user = db.Key.from_path('UserModel', int(userid))
    if user:
        return db.get(user)
    else:
        return None
        
def verify_user(userid_cookie):
    userid = verify_cookie(userid_cookie)
    if userid:
        user = validate_user(userid)
        if user:
            return userid, user
        else:
            return None
    else:
        return None, None
    
def generate_seats(alpha, numeric):
    seats = []
    for a in alpha:
        for n in range(1, numeric + 1):
            seats.append(a + str(n))
    return seats
    
def reset_seats():
    alpha  = 'ABCDEFGHIJKL'
    numeric = 20
    seats = generate_seats(alpha, numeric)
    alpha = 'M'
    numeric = 14
    seats += generate_seats(alpha, numeric)
    
    old_seats = db.GqlQuery('select * from SeatModel')
    db.delete(old_seats)
    # for seat in old_seats:
        # seat.key.delete()
    
    for seat in seats:
        status = 'available'
        if (seat[0] < 'C'):
            status = 'reserved'
        new_seat = models.SeatModel(seatNumber = seat,
                                    seatLocation = 'center',
                                    status = status)
        new_seat.put()

def cmp_seat_numbers(seatx, seaty):
    x = seatx.seatNumber
    y = seaty.seatNumber
    if (x[0] > y[0]):
        return 1
    elif (x[0] == y[0]):
        xnum = int(x[1:])
        ynum = int(y[1:])
        return xnum - ynum
    else:
        return -1
    
def generate_mID(handler):
    #this function creates a new session
    #assign a random ID, then check if that ID is already in the dictionary,
    #keep assigning a new one if it is in the dictionary
    #The dictionary data must be scrubbed _before_ the cookie expires,
    #else a new cookie with the same mID with an expired one might get access to the old data
    mID = hex(int(random.random()*1e9))[2:]
    while messageDict.has_key(mID):
        mID = hex(int(random.random()*1e9))[2:]
    #set a cookie with session ID (mID),
    #then check session dictionary for old cookie infos, and clean them
    handler.response.set_cookie('mID', securify_cookie(mID), expires = (datetime.datetime.now() + datetime.timedelta(days = 1)), path = '/')
    threshhold = datetime.datetime.now() - datetime.timedelta(days = 0.75)
    for k, v in messageDict.items():
        if v['time'] < threshhold:
            messageDict.pop(k)
    return mID
    
def assign_session_message(handler, mID, message):
    if (not mID) or (not messageDict.has_key(mID)):
        mID = generate_mID(handler)
    messageDict[mID] = {'message':message, 'time':datetime.datetime.now()}
    
def extract_session_message(mID):
    if (not mID) or (not messageDict.has_key(mID)):
        return ''
    else:
        message = messageDict[mID]['message']
        messageDict[mID]['message'] = ''
        messageDict[mID]['time'] = datetime.datetime.now()
        return message
        