﻿from __future__ import absolute_import, division, unicode_literals
import xbmc, xbmcplugin, xbmcaddon
import xbmcgui
import xbmcvfs
import socket
import json
import xml.etree.ElementTree as ET

from os import path
from utils import addon_name, addon_icon, addon_getSetting, log as mylog

class NFOUpdaterNew():
    def __init__(self):
        dialog = xbmcgui.Dialog()
        self.log("Line 15: __init__", 1)
        self.methodDict = {"VideoLibrary.OnUpdate": self.VideoLibraryOnUpdate,
                          }
        
        
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.setblocking(1)
        # Hard coded IP and Port 
        self.s.connect((addon_getSetting('jsonrpcIP'),int(addon_getSetting('jsonrpcPort'))))
        xbmc.sleep(4000)
        dialog.ok("Auf gehts", "VideoLibrary.OnUpdate muss funktionieren!")

    def log(self, msg, level=1):
        mylog(msg, name=self.__class__.__name__, level=level)


    def ThisHandlMSG(self, thisstrg):
        jsonmsg = json.loads(thisstrg)        
        method = jsonmsg['method']
        if method in self.methodDict:
            methodHandler = self.methodDict[method]
            methodHandler(jsonmsg)

    def KODIlisten(self):
        currentBuffer = []
        thisstrg = ''
        depth = 0
        
        monit = xbmc.Monitor()
        while not monit.abortRequested():
        #while not xbmc.abortRequested:
            self.log("Line 46: KODIlisten()", 1)
            chunk = self.s.recv(1)
            currentBuffer.append(chunk)
            if chunk == '{':
                depth += 1
            elif chunk == '}':
                depth -= 1
                if not depth:
                    thisstrg = ''.join(currentBuffer)
                    self.ThisHandlMSG(thisstrg)
                    currentBuffer = []
        self.s.close()

    def VideoLibraryOnUpdate(self, jsonmsg):
        self.log("Line 64: VideoLibraryOnUpdate", 1)
        dialog.ok("VideoLibraryOnUpdate", "Wir sind in der VideoLibraryOnUpdate()")
        try:
            if (("id" in jsonmsg["params"]["data"]["item"]) and ("type" in jsonmsg["params"]["data"]["item"]) and ("playcount" in jsonmsg["params"]["data"])):
                itemid = jsonmsg["params"]["data"]["item"]["id"]
                itemtype = jsonmsg["params"]["data"]["item"]["type"]
                itemplaycount = jsonmsg["params"]["data"]["playcount"]
                
                self.log("Line 71: Film or series: " + itemtype, 1)
                if itemtype == u'movie':
                    thisstrg = xbmc.executeJSONRPC('{"jsonrpc":"2.0","method":"VideoLibrary.GetMovieDetails","params":{"movieid":%d,"properties":["file"]},"id":1}' %(itemid) )
                    jsonmsg = json.loads(thisstrg)
                    filepath = jsonmsg["result"]["moviedetails"]["file"]
                    self.log("Line 76: JSONRPC: " + thisstrg, 1)
                    self.log("Line 77: Filepath: " + filepath, 1)
                    self.updateMyNFO(filepath, itemplaycount)
                
                ## When a season is marked as un-/watched, all episodes are edited
                if itemtype == u'episode':
                    thisstrg = xbmc.executeJSONRPC('{"jsonrpc":"2.0","method":"VideoLibrary.GetEpisodeDetails","params":{"episodeid":%s,"properties":["file"]},"id":1}' %(str(itemid)) )
                    jsonmsg = json.loads(thisstrg)
                    filepath = jsonmsg["result"]["episodedetails"]["file"]
                    self.log("Line 85: JSONRPC: " + thisstrg, 1)
                    self.log("Line 86: Filepath: " + filepath, 1)
                    self.updateMyNFO(filepath, itemplaycount)
        except:
            msgfake = ""
            self.log("Line 90: Error (item not found): " + str(jsonmsg), 1)
    
    def updateMyNFO(self, filepath, playcount):
        filepath = filepath.replace(path.splitext(filepath)[1], '.nfo')
        self.log("Line 94: NFO File: " + filepath, 1)
        
        if xbmcvfs.exists(filepath):
            sFile = xbmcvfs.File(filepath)
            currentBuffer = []
            thisstrg = ''
            while True:
                buf = sFile.read(1024)
                currentBuffer.append(buf)
                if not buf:
                    thisstrg = ''.join(currentBuffer)                    
                    break
                
            sFile.close()
            
            tree = ET.ElementTree(ET.fromstring(thisstrg))
            root = tree.getroot()
            
            w = root.find('watched')
            if w is None:
                self.log("Line 114: NFO add TAG <watched>", 1)
                w = ET.SubElement(root, 'watched')
            if playcount > 0:
                w.text = 'true'
            else:
                w.text = 'false'
            
            p = root.find('playcount')
            if p is None:
                self.log("Line 123: NFO add TAG <playcount>", 1)
                p = ET.SubElement(root, 'playcount')
                
            p.text = str(playcount)
            self.PrintFriendlyXML(root)
            
            thisstrg = ET.tostring(root, encoding='UTF-8')
            if thisstrg:
                self.log("Line 131: Write NFO File: " + filepath, 1)
                dFile = xbmcvfs.File(filepath, 'w')
                dFile.write(thisstrg) ##String thisstrg or bytearray: bytearray(thisstrg)
                dFile.close()
                self.log("Line 135: NFO successfully written: " + filepath, 1)
            else:
                self.log("Line 137: Error in 'thisstrg': " + thisstrg, 1)
        else:
            self.log("Line 139: File not found': " + filepath, 1)

    def PrintFriendlyXML(self, elem, level=0):
        i = '\n' + level * '   '
        if len(elem):
            if not elem.text or not elem.text.strip():
                elem.text = i + "  "
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
            for elem in elem:
                self.PrintFriendlyXML(elem, level+1)
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
        else:
            if level and (not elem.tail or not elem.tail.strip()):
                elem.tail = i

if __name__ == '__main__':
    MY = NFOUpdaterNew()
    MY.KODIlisten()
    del MY
