import json
from kodi_six import xbmc, xbmcgui, xbmcvfs
from . import utils as utils

class BackupSetManager:
    jsonFile = xbmc.translatePath(utils.data_dir() + "custom_paths.json")
    paths = None
    
    def __init__(self):
        self.paths = {}
        
        #try and read in the custom file
        self._readFile()

    def addSet(self,aSet):
        self.paths[aSet['name']] = {'root':aSet['root'],'dirs':[{"type":"include","path":aSet['root'],'recurse':True}]}

        #save the file
        self._writeFile()

    def updateSet(self,name,aSet):
        self.paths[name] = aSet

        #save the file
        self._writeFile()

    def deleteSet(self,index):
        #match the index to a key
        keys = self.getSets()

        #delete this set
        del self.paths[keys[index]]

        #save the file
        self._writeFile()
    
    def getSets(self):
        #list all current sets by name
        keys = list(self.paths.keys())
        keys.sort()

        return keys

    def getSet(self,index):
        keys = self.getSets();

        #return the set at this index
        return {'name':keys[index],'set':self.paths[keys[index]]}

    def validateSetName(self,name):
        return (name not in self.getSets())

    def _writeFile(self):
        #create the custom file
        aFile = xbmcvfs.File(self.jsonFile,'w')
        aFile.write(json.dumps(self.paths))
        aFile.close()
    
    def _readFile(self):
        
        if(xbmcvfs.exists(self.jsonFile)):

            #read in the custom file
            aFile = xbmcvfs.File(self.jsonFile)

            #load custom dirs
            self.paths = json.loads(aFile.read())
            aFile.close()
        else:
            #write a blank file
            self._writeFile()

class AdvancedBackupEditor:
    dialog = None

    def __init__(self):
        self.dialog = xbmcgui.Dialog()

    def _cleanPath(self,root,path):
        return path[len(root)-1:]

    def _validatePath(self,root,path):
        return path.startswith(root)

    def createSet(self):
        backupSet = None
    
        name = self.dialog.input(utils.getString(30110),defaultt='Backup Set')

        if(name != None):

            #give a choice to start in home or enter a root path
            enterHome = self.dialog.yesno(utils.getString(30111),line1=utils.getString(30112) + " - " + utils.getString(30114),line2=utils.getString(30113) + " - " + utils.getString(30115),nolabel=utils.getString(30112),yeslabel=utils.getString(30113))

            rootFolder = 'special://home'
            if(enterHome):
                rootFolder = self.dialog.input(utils.getString(30116),defaultt=rootFolder)

                #direcotry has to end in slash
                if(rootFolder[:-1] != '/'):
                    rootFolder = rootFolder + '/'

                #check that this path even exists
                if(not xbmcvfs.exists(xbmc.translatePath(rootFolder))):
                    self.dialog.ok(utils.getString(30117),utils.getString(30118),rootFolder)
                    return None
            else:
                #select path to start set
                rootFolder = self.dialog.browse(type=0,heading=utils.getString(30119),shares='files',defaultt=rootFolder)

            backupSet = {'name':name,'root':rootFolder}
    
        return backupSet

    def editSet(self,name,backupSet):
        optionSelected = ''
        rootPath = backupSet['root']
        utils.log(rootPath)
        while(optionSelected != -1):
            options = [xbmcgui.ListItem(utils.getString(30120),"Exclude a specific folder from this backup set"),xbmcgui.ListItem(utils.getString(30135),"Include a specific folder to this backup set"),xbmcgui.ListItem(rootPath,utils.getString(30121))]

            for aDir in backupSet['dirs']:
                if(aDir['type'] == 'exclude'):
                    options.append(xbmcgui.ListItem(self._cleanPath(rootPath,aDir['path']),"%s: %s" % ("Type",utils.getString(30129))))
                elif(aDir['type'] == 'include'):
                    options.append(xbmcgui.ListItem(self._cleanPath(rootPath,aDir['path']),"%s: %s | %s: %s" % ("Type",utils.getString(30134),"Include Sub Folders",str(aDir['recurse']))))

            optionSelected = self.dialog.select(utils.getString(30122) + ' ' +  name,options,useDetails=True)

            if(optionSelected == 0 or optionSelected == 1):
                #add a folder, will equal root if cancel is hit
                addFolder = self.dialog.browse(type=0,heading=utils.getString(30120),shares='files',defaultt=backupSet['root'])
                
                if(addFolder.startswith(rootPath)):
                    
                    if(not any(addFolder == aDir['path'] for aDir in backupSet['dirs'])):
                        #cannot add root as an exclusion
                        if(optionSelected == 0 and addFolder != backupSet['root']):
                            backupSet['dirs'].append({"path":addFolder,"type":"exclude"})
                        elif(optionSelected == 1):
                            #can add root as inclusion
                            backupSet['dirs'].append({"path":addFolder,"type":"include","recurse":True})
                    else:
                        #this path is already part of another include/exclude rule
                        self.dialog.ok(utils.getString(30117),utils.getString(30137),addFolder)
                else:
                    #folder must be under root folder
                    self.dialog.ok(utils.getString(30117), utils.getString(30136),rootPath)
            elif(optionSelected == 2):
                self.dialog.ok(utils.getString(30121),utils.getString(30130),backupSet['root'])
            elif(optionSelected > 2):
                
                cOptions = ['Delete']
                if(backupSet['dirs'][optionSelected - 3]['type'] == 'include'):
                    cOptions.append('Toggle Sub Folders')
                    
                contextOption = self.dialog.contextmenu(cOptions)
                
                if(contextOption == 0):
                    if(self.dialog.yesno(heading=utils.getString(30123),line1=utils.getString(30128))):
                        #remove folder
                        del backupSet['dirs'][optionSelected - 3]
                elif(contextOption == 1 and backupSet['dirs'][optionSelected - 3]['type'] == 'include'):
                    #toggle if this folder should be recursive
                    backupSet['dirs'][optionSelected - 3]['recurse'] = not backupSet['dirs'][optionSelected - 3]['recurse']

        return backupSet
    

    def showMainScreen(self):
        exitCondition = ""
        customPaths = BackupSetManager()

        #show this every time
        self.dialog.ok(utils.getString(30036),utils.getString(30037))
 
        while(exitCondition != -1):
            #load the custom paths
            options = [xbmcgui.ListItem(utils.getString(30126),'',utils.addon_dir() + '/resources/images/plus-icon.png')]
        
            for index in range(0,len(customPaths.getSets())):
                aSet = customPaths.getSet(index)
                options.append(xbmcgui.ListItem(aSet['name'],utils.getString(30121) + ': ' + aSet['set']['root'],utils.addon_dir() + '/resources/images/folder-icon.png'))
            
            #show the gui
            exitCondition = self.dialog.select(utils.getString(30125),options,useDetails=True)
        
            if(exitCondition >= 0):
                if(exitCondition == 0):
                    newSet = self.createSet()

                    #check that the name is unique
                    if(customPaths.validateSetName(newSet['name'])):
                        customPaths.addSet(newSet)
                    else:
                        self.dialog.ok(utils.getString(30117), utils.getString(30138),newSet['name'])
                else:
                    #bring up a context menu
                    menuOption = self.dialog.contextmenu([utils.getString(30122),utils.getString(30123)])

                    if(menuOption == 0):
                        #get the set
                        aSet = customPaths.getSet(exitCondition -1)
                        
                        #edit the set
                        updatedSet = self.editSet(aSet['name'],aSet['set'])

                        #save it
                        customPaths.updateSet(aSet['name'],updatedSet)
                    
                    elif(menuOption == 1):
                        if(self.dialog.yesno(heading=utils.getString(30127),line1=utils.getString(30128))):
                            #delete this path - subtract one because of "add" item
                            customPaths.deleteSet(exitCondition -1)

    def copySimpleConfig(self):
        #disclaimer in case the user hit this on accident
        shouldContinue = self.dialog.yesno(utils.getString(30139),utils.getString(30140),utils.getString(30141))

        if(shouldContinue):
            source = xbmc.translatePath(utils.addon_dir() + "/resources/data/default_files.json")
            dest = xbmc.translatePath(utils.data_dir() + "/custom_paths.json")

            xbmcvfs.copy(source,dest)

              

