from __future__ import print_function
#######################################################################
#
#    Push Service for Enigma-2
#    Coded by betonme (c) 2012 <glaserfrank(at)gmail.com>
#    Support: http://www.i-have-a-dreambox.com/wbb2/thread.php?threadid=167779
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of the GNU General Public License
#    as published by the Free Software Foundation; either version 2
#    of the License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#######################################################################

# Config
from Components.config import ConfigYesNo, ConfigText, ConfigNumber, NoSave

# Plugin internal
from Plugins.Extensions.PushService.__init__ import _
from Plugins.Extensions.PushService.ControllerBase import ControllerBase

# Plugin specific
import os


# Constants
SUBJECT = _("Free space warning")
BODY    = _("Free disk space limit has been reached:\n") \
				+ _("Path:  %s\n") \
				+ _("Limit: %d GB\n") \
				+ _("Left:  %s")


class FreeSpace(ControllerBase):
	
	ForceSingleInstance = False
	
	def __init__(self):
		# Is called on instance creation
		ControllerBase.__init__(self)
		
		# Default configuration
		self.setOption( 'wakehdd',  NoSave(ConfigYesNo(  default = False )),                                  _("Allow HDD wake up") )
		self.setOption( 'path',     NoSave(ConfigText(   default = "/media/hdd/movie", fixed_size = False )), _("Where to check free space") )
		self.setOption( 'limit',    NoSave(ConfigNumber( default = 100 )),                                    _("Free space limit in GB") )
	
	def run(self, callback, errback):
		# At the end a plugin has to call one of the functions: callback or errback
		# Callback should return with at least one of the parameter: Header, Body, Attachment
		# If empty or none is returned, nothing will be sent
		path = self.getValue('path')
		limit = self.getValue('limit')
		
		if not self.getValue('wakehdd'):
			#Adapted from: from Components.Harddisk import findMountPoint
			def mountpoint(path):
				path = os.path.realpath(path)
				if os.path.ismount(path) or len(path)==0: return path
				return mountpoint(os.path.dirname(path))
						
			def getDevicebyMountpoint(hdm, mountpoint):
				for x in hdm.partitions[:]:
					if x.mountpoint == mountpoint:
						return x.device
				return None
			
			def getHDD(hdm, part):
				for hdd in hdm.hdd:
					if hdd.device == part[:3]:
						return hdd
				return None
			
			# User specified to avoid HDD wakeup if it is sleeping
			from Components.Harddisk import harddiskmanager
			dev = getDevicebyMountpoint( harddiskmanager, mountpoint(path) )
			if dev is not None:
				hdd = getHDD( harddiskmanager, dev )
				if hdd is not None:
					if hdd.isSleeping():
						# Don't wake up HDD
						print(_("[FreeSpace] HDD is idle: ") + str(path))
						callback()
		
		# Check free space on path
		if os.path.exists( path ):
			stat = os.statvfs( path )
			free = ( stat.f_bavail if stat.f_bavail!=0 else stat.f_bfree ) * stat.f_bsize / 1024 / 1024 # MB
			if limit > (free/1024): #GB
				if free >= 10*1024:	#MB
					free = "%d GB" %(free/1024)
				else:
					free = "%d MB" %(free)
				# Not enough free space
				callback( SUBJECT, BODY % (path, limit, free) )
			else:
				# There is enough free space
				callback()
