#---------------
# Author: Yomara Acevedo
# Date: 27 Apr 2017
# Purpose: Print received MQTT post
#---------------

import paho.mqtt.client as mqtt
import json
import sqlite3
import struct

from datetime import datetime

from interpretCharacter import whoAreYou
from interpretCharacter import whereAreYou

endGameStats = {}
DB_Name = "SuddenDeath.db"

#===========================================================================
# Database Manager Class

class DatabaseManager():
	def __init__(self):
		self.conn = sqlite3.connect(DB_Name)
		self.conn.execute('pragma foreign_keys = on')
		self.conn.commit()
		self.cur = self.conn.cursor()
		
	def add_del_update_db_record(self, sql_query, args=()):
		self.cur.execute(sql_query, args)
		self.conn.commit()
		return

	def __del__(self):
		self.cur.close()
		self.conn.close()
#===========================================================================

def on_connect(client, userdata, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("smashStats/#")

# Translate ASCII into HEX
def on_message(client, userdata, msg):
    charID = list(msg.payload)
    if len(charID) != 4:
        for x in range(4-len(charID)):
            charID.append('\0')

    ## TOPIC: smashStats/gameinfo/# =========================
    if msg.topic == "smashStats/gameinfo/stage":
        stageName = whereAreYou(hex(ord(charID[0])))
        print("Stage: "+stageName)

        endGameStats['gameinfo_Stage'] = stageName

    elif msg.topic == "smashStats/gameinfo/time": #int
        charID = list(reversed(msg.payload))
        if len(charID) != 4:
            for x in range(4-len(charID)):
                charID = ['\0'] + charID
        variable = "".join(x.encode('hex') for x in charID)
        endTime = struct.unpack('!i', variable.decode('hex'))[0]
        print("Game duration: "+str(endTime)+" frames")
        
        endGameStats['gameinfo_time'] = endTime



    ## TOPIC: smashStats/player1/# =========================
    elif msg.topic == "smashStats/player1/characterID":
        characterName = whoAreYou(hex(ord(charID[0])))
        print("Player 1: "+characterName)

        endGameStats['P1_characterID'] = characterName

    elif msg.topic == "smashStats/player1/center_control": #int
        charID = list(reversed(msg.payload))
        if len(charID) != 4:
            for x in range(4-len(charID)):
                charID = ['\0'] + charID
        variable = "".join(x.encode('hex') for x in charID)
        centerCont = struct.unpack('!i', variable.decode('hex'))[0]
        print("P1 center control: "+str(centerCont)+" frames")

        endGameStats['P1_centerCont'] = centerCont

    elif msg.topic == "smashStats/player1/roll_count": #int
        charID = list(reversed(msg.payload))
        if len(charID) != 4:
            for x in range(4-len(charID)):
                charID = ['\0'] + charID
        variable = "".join(x.encode('hex') for x in charID)
        rolls = struct.unpack('!i', variable.decode('hex'))[0]
        print("P1 roll count: "+str(rolls))

        endGameStats['P1_rolls'] = rolls

    elif msg.topic == "smashStats/player1/dodge_count": #int
        charID = list(reversed(msg.payload))
        if len(charID) != 4:
            for x in range(4-len(charID)):
                charID = ['\0'] + charID
        variable = "".join(x.encode('hex') for x in charID)
        dodges = struct.unpack('!i', variable.decode('hex'))[0]
        print("P1 dodge count: "+str(dodges))

        endGameStats['P1_dodges'] = dodges

    elif msg.topic == "smashStats/player1/apm": #float
        variable = "".join(x.encode('hex') for x in charID)
        apm = struct.unpack('!f', variable.decode('hex'))[0]
        print("P1 actions per minute: "+str(apm))

        endGameStats['P1_apm'] = apm

    elif msg.topic == "smashStats/player1/avg_combo_damage": #float
        variable = "".join(x.encode('hex') for x in charID)
        avg_combo_dmg = struct.unpack('!f', variable.decode('hex'))[0]
        print("P1 average combo damage: "+str(avg_combo_dmg)+"%")

        endGameStats['P1_avg_combo_dmg'] = avg_combo_dmg

    elif msg.topic == "smashStats/player1/avg_hits_p_combo": #float
        variable = "".join(x.encode('hex') for x in charID)
        avg_hits_p_combo = struct.unpack('!f', variable.decode('hex'))[0]
        print("P1 average hits per combo: "+str(avg_hits_p_combo))

        endGameStats['P1_hits_p_combo'] = avg_hits_p_combo

    elif msg.topic == "smashStats/player1/edge_guard_eff": #int
        variable = "".join(x.encode('hex') for x in charID)
        edge_guard_eff = struct.unpack('!f', variable.decode('hex'))[0]
        print("P1 edge guard efficiencty: "+str(edge_guard_eff)+"%")

        endGameStats['P1_edge_guard_eff'] = edge_guard_eff

    elif msg.topic == "smashStats/player1/avg_death_percent": #float
        variable = "".join(x.encode('hex') for x in charID)
        avg_death = struct.unpack('!f', variable.decode('hex'))[0]
        print("P1 average death percent: "+str(avg_death)+"%")

        endGameStats['P1_avg_death'] = avg_death



    ## TOPIC: smashStats/player2/# =========================
    elif msg.topic == "smashStats/player2/characterID":
        characterName = whoAreYou(hex(ord(charID[0])))
        print("Player 2: "+characterName)

        endGameStats['P2_characterID'] = characterName

    elif msg.topic == "smashStats/player2/center_control": #int
        charID = list(reversed(msg.payload))
        if len(charID) != 4:
            for x in range(4-len(charID)):
                charID = ['\0'] + charID
        variable = "".join(x.encode('hex') for x in charID)
        centerCont = struct.unpack('!i', variable.decode('hex'))[0]
        print("P2 center control: "+str(centerCont)+" frames")

        endGameStats['P2_centerCont'] = centerCont

    elif msg.topic == "smashStats/player2/roll_count": #int
        charID = list(reversed(msg.payload))
        if len(charID) != 4:
            for x in range(4-len(charID)):
                charID = ['\0'] + charID
        variable = "".join(x.encode('hex') for x in charID)
        rolls = struct.unpack('!i', variable.decode('hex'))[0]
        print("P2 roll count: "+str(rolls))
        
        endGameStats['P2_rolls'] = rolls

    elif msg.topic == "smashStats/player2/dodge_count": #int
        charID = list(reversed(msg.payload))
        if len(charID) != 4:
            for x in range(4-len(charID)):
                charID = ['\0'] + charID
        variable = "".join(x.encode('hex') for x in charID)
        dodges = struct.unpack('!i', variable.decode('hex'))[0]
        print("P2 dodge count: "+str(dodges))

        endGameStats['P2_dodges'] = dodges

    elif msg.topic == "smashStats/player2/apm": #float
        variable = "".join(x.encode('hex') for x in charID)
        apm = struct.unpack('!f', variable.decode('hex'))[0]
        print("P2 actions per minute: "+str(apm))

        endGameStats['P2_apm'] = apm

    elif msg.topic == "smashStats/player2/avg_combo_damage": #float
        variable = "".join(x.encode('hex') for x in charID)
        avg_combo_dmg = struct.unpack('!f', variable.decode('hex'))[0]
        print("P2 average combo damage: "+str(avg_combo_dmg)+"%")

        endGameStats['P2_avg_combo_dmg'] = avg_combo_dmg

    elif msg.topic == "smashStats/player2/avg_hits_p_combo": #float
        variable = "".join(x.encode('hex') for x in charID)
        avg_hits_p_combo = struct.unpack('!f', variable.decode('hex'))[0]
        print("P2 average hits per combo: "+str(avg_hits_p_combo))

        endGameStats['P2_hits_p_combo'] = avg_hits_p_combo

    elif msg.topic == "smashStats/player2/edge_guard_eff": #int
        variable = "".join(x.encode('hex') for x in charID)
        edge_guard_eff = struct.unpack('!f', variable.decode('hex'))[0]
        print("P2 edge guard efficiencty: "+str(edge_guard_eff)+"%")

        endGameStats['P2_edge_guard_eff'] = edge_guard_eff

    elif msg.topic == "smashStats/player2/avg_death_percent": #float
        variable = "".join(x.encode('hex') for x in charID)
        avg_death = struct.unpack('!f', variable.decode('hex'))[0]
        print("P2 average death percent: "+str(avg_death)+"%")

        endGameStats['P2_avg_death'] = avg_death

    try: #once the variables we want have been filled, we publish it
        endGameStats['P1_characterID']
        endGameStats['P2_characterID']
        endGameStats['gameinfo_Stage']
        endGameStats['gameinfo_time']
        endGameStats['P1_rolls']
        endGameStats['P2_rolls']
        endGameStats['P1_dodges']
        endGameStats['P2_dodges']
        endGameStats['P1_apm']
        endGameStats['P2_apm']
        endGameStats['P1_avg_death']
        endGameStats['P2_avg_death']
        endGameStats['P1_avg_combo_dmg']
        endGameStats['P2_avg_combo_dmg']
        endGameStats['P1_hits_p_combo']
        endGameStats['P2_hits_p_combo']
        endGameStats['P1_edge_guard_eff']
        endGameStats['P2_edge_guard_eff']
        endGameStats['date_n_time'] = (datetime.today()).strftime("%d-%m-%Y %H:%M:%S")
        client.publish("smashStats/endGameStats",json.dumps(endGameStats))

        pushIntoDB(json.dumps(endGameStats))
        
        endGameStats.clear() #clear all variables to prep for the next match

        print("")
        print("END GAME")
        print("")
        print("")
    except KeyError:
        return

    return

def pushIntoDB(stats): #send variables into a database.
    json_Dict = json.loads(stats)
    P1_characterID = json_Dict['P1_characterID']
    P2_characterID = json_Dict['P2_characterID']
    gameinfo_Stage = json_Dict['gameinfo_Stage']
    gameinfo_time = json_Dict['gameinfo_time']
    date_n_time = json_Dict['date_n_time']
    P1_rolls = json_Dict['P1_rolls']
    P2_rolls = json_Dict['P2_rolls']
    P1_dodges = json_Dict['P1_dodges']
    P2_dodges = json_Dict['P2_dodges']
    P1_apm = json_Dict['P1_apm']
    P2_apm = json_Dict['P2_apm']
    P1_avg_death = json_Dict['P1_avg_death']
    P2_avg_death = json_Dict['P2_avg_death']
    P1_avg_combo_dmg = json_Dict['P1_avg_combo_dmg']
    P2_avg_combo_dmg = json_Dict['P2_avg_combo_dmg']
    P1_hits_p_combo = json_Dict['P1_hits_p_combo']
    P2_hits_p_combo = json_Dict['P2_hits_p_combo']
    P1_edge_guard_eff = json_Dict['P1_edge_guard_eff']
    P2_edge_guard_eff = json_Dict['P2_edge_guard_eff']

    dbObj = DatabaseManager()
    dbObj.add_del_update_db_record("insert into suddeath_Master (date_n_time, gameinfo_Stage, gameinfo_time, P1_characterID, P2_characterID, P1_rolls, P2_rolls, P1_dodges, P2_dodges, P1_apm, P2_apm, P1_avg_death, P2_avg_death, P1_avg_combo_dmg, P2_avg_combo_dmg, P1_hits_p_combo, P2_hits_p_combo, P1_edge_guard_eff, P2_edge_guard_eff) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[date_n_time, gameinfo_Stage, gameinfo_time, P1_characterID, P2_characterID, P1_rolls, P2_rolls, P1_dodges, P2_dodges, P1_apm, P2_apm, P1_avg_death, P2_avg_death, P1_avg_combo_dmg, P2_avg_combo_dmg, P1_hits_p_combo, P2_hits_p_combo, P1_edge_guard_eff, P2_edge_guard_eff])
    dbObj.add_del_update_db_record("insert into suddeath_P1 (date_n_time, gameinfo_Stage, gameinfo_time, P1_characterID, P1_rolls, P1_dodges, P1_apm, P1_avg_death, P1_avg_combo_dmg, P1_hits_p_combo, P1_edge_guard_eff) values (?,?,?,?,?,?,?,?,?,?,?)",[date_n_time, gameinfo_Stage, gameinfo_time, P1_characterID, P1_rolls, P1_dodges, P1_apm, P1_avg_death, P1_avg_combo_dmg, P1_hits_p_combo, P1_edge_guard_eff])
    dbObj.add_del_update_db_record("insert into suddeath_P2 (date_n_time, gameinfo_Stage, gameinfo_time, P2_characterID, P2_rolls, P2_dodges, P2_apm, P2_avg_death, P2_avg_combo_dmg, P2_hits_p_combo, P2_edge_guard_eff) values (?,?,?,?,?,?,?,?,?,?,?)",[date_n_time, gameinfo_Stage, gameinfo_time, P2_characterID, P2_rolls, P2_dodges, P2_apm, P2_avg_death, P2_avg_combo_dmg, P2_hits_p_combo, P2_edge_guard_eff])
    del dbObj
    print "Inserted data into Database"

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("127.0.0.1", 1883, 60)

client.loop_forever()
