# -*- coding: utf-8 -*-
import re
from os import chmod as os_chmod, remove as os_remove
from datetime import date

from Plugins.Bp.geminimain.gLocale import _
from Plugins.Bp.geminimain.gTools import libgeminimain, cleanexit, BoxType, getFreeSize, pathExists
from Plugins.Bp.geminimain.plugin import cgevent
from Plugins.Bp.geminimain.WidgetConfig import gConfigWindow, gConfigOnOff, gConfigDirectory, gConfigSelection, CONFIGSEPERATOR

from Components.config import config, NoSave, getConfigListEntry, ConfigText
from Screens.Console import Console

#----------------------------------------------------------------------------------------

TMP_ROOT= "/var/tmp/.tmp-root"
BACKUP_ROOT= "/.backup-root"
BACKUP_SCRIPT= "/var/tmp/backup.sh"
BACKUP_LOG= "/geminibackup.log"

#----------------------------------------------------------------------------------------

from os import statvfs
def getSize(path):
	try:
		stat = statvfs(path)
		return (stat.f_blocks - stat.f_bfree) * stat.f_bsize
	except OSError:
		return -1
	
#----------------------------------------------------------------------------------------

class gBackup(gConfigWindow):
	def __init__(self, session):
		self.session = session
		menu = [(1, "xz (%s)"%_("fast")),
			#(2, "xz (%s)"%_("normal")),
			(3, "xz (%s)"%_("best")),
			(11, "gz (%s)"%_("fast")),
			#(13, "gz (%s)"%_("normal")),
			(19, "gz (%s)"%_("best")),
			#(21, "bz2 (%s)"%_("fast")),(23, "bz2 (%s)"%_("normal")),(29, "bz2 (%s)"%_("best"))
			]
		
		if getSize("/")/1024/1024 < 312:
			menu = [(-1, "Busybox xz") ] + menu
			
		config.bp.path = NoSave(gConfigDirectory(default=cgevent.getConfig("backuplocation","/media/hdd"), visible_width=35))
		config.bp.name = NoSave(ConfigText(default=cgevent.getConfig("imagename","gemini-image-bak"), visible_width = 50, fixed_size = False))
		config.bp.reset = NoSave(gConfigOnOff(default=cgevent.getConfig("factoryreset",0)))
		config.bp.compression = NoSave(gConfigSelection(default=cgevent.getConfig("xzcompression",1), choices=menu))
		config.bp.debug = NoSave(gConfigOnOff(default=cgevent.getConfig("backupdebug",0)))
		config.bp.logpath = NoSave(gConfigDirectory(default=cgevent.getConfig("backuploglocation","/var/log"), visible_width=35))
		gConfigWindow.__init__(self, session, title=_("Backup"), icon="geminibackup/icon_backup.png", redbutton=_("log-file"))
		
		self.onLayoutFinish.append(self.__setList)
	
	def __setList(self):
		list=[]
		list.append(getConfigListEntry(_("directory for files:"), config.bp.path))
		list.append(getConfigListEntry(_("Name") + ":", config.bp.name))
		list.append(getConfigListEntry(_("Factory Reset"), config.bp.reset))
		list.append(getConfigListEntry(_("Compression"), config.bp.compression))
		list.append(CONFIGSEPERATOR())
		list.append(getConfigListEntry(_("Debug"), config.bp.debug))
		
		if config.bp.debug.value:
			list.append(getConfigListEntry(_("directory for logfile:"), config.bp.logpath))
		self.SetConfList(list)	
		
	def KeyGreen(self):
		cgevent.setConfig("backuplocation",config.bp.path.value)
		cgevent.setConfig("factoryreset",config.bp.reset.value)
		cgevent.setConfig("xzcompression",config.bp.compression.value)
		cgevent.setConfig("backupdebug",config.bp.debug.value)
		cgevent.setConfig("backuploglocation",config.bp.logpath.value)
		if len([i for i in config.bp.name.value if i not in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+0123456789"]):
			myvalue = config.bp.name.value
			config.bp.name = NoSave(ConfigText(default=cgevent.getConfig("imagename","gemini-image-bak"), visible_width = 50, fixed_size = False))
			from Screens.MessageBox import MessageBox
			self.session.open(MessageBox, ("Filename '%s' contains bad expression or ' '!\nPlease select a different name") % myvalue, MessageBox.TYPE_ERROR, timeout=8)
		else:
			cleanName = "".join([i for i in config.bp.name.value if i in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+0123456789"])
			config.bp.name.setValue(cleanName if (cleanName != "") else "gemini-image-bak")
			cgevent.setConfig("imagename",config.bp.name.value)
			backuproot = config.bp.path.value + BACKUP_ROOT
			path = config.bp.path.value + "/" + config.bp.name.value + "-" + BoxType + "-" + date.today().strftime("%Y%m%d")
			ext = ""
			if config.bp.compression.value > 20:
				ext += ".tar.bz2"
			elif config.bp.compression.value > 9:
				ext += ".tar.gz"
			else:
				ext += ".tar.xz"
				
			if pathExists(path + ext):
				i = 1
				while pathExists(path + "(" + str(i) + ")" + ext):
					i += 1
				path = path + "\(" + str(i) + "\)" + ext
			else:
				path = path + ext
			
			if getFreeSize(config.bp.path.value) - 2 * getSize("/") < 0:
				from Screens.MessageBox import MessageBox
				self.session.open(MessageBox,_("Folder '%s'\nnot enough free space (>%dMB)!") %(config.bp.path.value, 2 * getSize("/")/1024/1024), MessageBox.TYPE_ERROR, timeout=8)
			else:
				if config.bp.debug.value:
					cmd = "#!/bin/sh\n"
					cmd += "echo '%s'\n" %_("backup debug mode please wait...")
					cmd += "echo '%s: %s'\n" %(_("log-file"),(config.bp.logpath.value + BACKUP_LOG))
					cmd += "set -x\n"
					cmd += "exec > %s 2>&1\n" %(config.bp.logpath.value + BACKUP_LOG)
					cmd += "cat %s\n" %BACKUP_SCRIPT
				else:
					cmd =""

				cmd += "echo \"*** gBackup `date` ***\"\n"
				cmd += "echo '%s'\n" %_("clean apt archive")
				cmd += "apt-get clean\n"
				cmd += "mkdir -p %s\n" %TMP_ROOT
				cmd += "mkdir -p %s\n" %backuproot
				cmd += "mount --bind / %s\n" %TMP_ROOT
				cmd += "echo '%s'\n" %_("copy files")
				cmd += "cp -Rf %s/* %s\n" % (TMP_ROOT ,backuproot)
				cmd += "umount %s\n" %TMP_ROOT
			
				if config.bp.reset.value:
					cmd += "echo '%s'\n" %_("Factory Reset on backup image")
					cmd += "rm -Rf %s/etc/enigma2\n" %backuproot
					cmd += "cp -Rf /usr/share/enigma2/defaults %s/etc/enigma2\n" %backuproot
					cmd += "cp -Rf /etc/enigma2/gemini_* %s/etc/enigma2\n" %backuproot
					cmd += "cp -Rf /etc/enigma2/gMultiQuickButton %s/etc/enigma2\n" %backuproot
			
				cmd += "cd %s\n" %backuproot
			
				if config.bp.debug.value:
					cmd += "ls -l %s\n" %backuproot
			
				if config.bp.compression.value < 0:
					cmd += "echo 'tar: %s'\n" % _("image data compression...")
					cmd += "tar -cJf %s *\n" %path
				else:
					cmd += "echo 'tar: %s'\n" %_("backup image")
					cmd += "tar -cvf %s * > /dev/null\n" %(path[:-3] if (config.bp.compression.value < 20) else path[:-4])
				
					if config.bp.compression.value > 20:
						cmd += "echo 'bzip2: %s'\n" %_("image data compression...")
						cmd += "bzip2 -%d %s\n" %(config.bp.compression.value-20, path[:-4])
					
					elif config.bp.compression.value > 9:
						cmd += "echo 'pigz: %s'\n" %_("image data compression...")
						cmd += "pigz -%d %s\n" %(config.bp.compression.value-10, path[:-3])
					
					elif pathExists("/usr/bin/pxz"):
						cmd += "echo 'pxz: %s'\n" %_("image data compression...")
						cmd += "pxz -%d -z %s\n" %(config.bp.compression.value, path[:-3])
					else:
						cmd += "echo 'xz: %s'\n" %_("image data compression...")
						cmd += "xz -%d -z %s\n" %(config.bp.compression.value, path[:-3])

				cmd += "cd %s\n" %config.bp.path.value
				cmd += "echo '%s'\n" %_("removing unused files")
				cmd += "rm -Rf %s\n" %backuproot
				sfileExists = "if [ -f '%s' ]; then echo '%s'; exit 0; else echo `ls -l %s | awk '{print $9\" (\" $5/1024/1024 \" MB)\"}`; echo '%s'; exit 1; fi;\n" %(path.replace("\\",""), _("backup finished!"),path.replace("\\",""), _("backup failed!"))
				cmd += sfileExists
				
				if config.bp.debug.value:
					with open(BACKUP_SCRIPT, 'w') as f:
						f.write(cmd)
					
					os_chmod(BACKUP_SCRIPT, 0755)
				
					self.session.open(Console,_("Backup"),[ BACKUP_SCRIPT, sfileExists ],closeOnSuccess = True)
				else:
					self.session.open(Console,_("Backup"),[ cmd ],closeOnSuccess = True)
				#print "\n>>>>>>>>>>>> gBackup DEBUG <<<<<<<<<<<<<\n",
				#print cmd
				#print ">>>>>>>>>>>> gBackup DEBUG <<<<<<<<<<<<<\n\n",
		
	def KeyLeft(self):
		gConfigWindow.KeyLeft(self)
		if self.GetIndex() == 5:
			self.__setList()
      
	def KeyRight(self):
		gConfigWindow.KeyRight(self)
		if self.GetIndex() == 5:
			self.__setList()
      
	def KeyRed(self):
		if pathExists(config.bp.logpath.value + BACKUP_LOG):
			self.session.open(Console,_("log-file"),["cat %s" %(config.bp.logpath.value + BACKUP_LOG)],closeOnSuccess = False)
		else:
			from Screens.MessageBox import MessageBox
			self.session.open(MessageBox, _("File '%s' not found!") %(config.bp.logpath.value + BACKUP_LOG), MessageBox.TYPE_ERROR, timeout=5)
	  
	def KeyExit(self):
		self.close()
		if pathExists(BACKUP_SCRIPT):
			os_remove(BACKUP_SCRIPT)
		cleanexit(__name__)
