import cryptobox.plugins.base
from cryptobox.core.exceptions import *

class volume_format_fs(cryptobox.plugins.base.CryptoBoxPlugin):

	pluginCapabilities = [ "volume" ]
	pluginVisibility = [ "volume" ]
	requestAuth = True
	rank = 60

	## map filesystem types to the appropriate arguments for 'mkfs'
	fsTypes = {
		"windows": "vfat",
		"linux": "ext3" }
	
	containerTypes = [ "luks", "plain" ]


	def doAction(self, store=None, fs_type="windows", container_type="luks", crypto_password=None, crypto_password2=None, confirm=None):
		if not fs_type in self.fsTypes.keys():
			self.cbox.info
			return "format_volume"
		self.hdf[self.hdf_prefix + "fs_type"] = fs_type
		self.hdf[self.hdf_prefix + "container_type"] = container_type
		for t in self.fsTypes.keys():
			self.hdf[self.hdf_prefix + "fs_types." + t] = t
		if store == "step1":
			if not confirm:
				self.cbox.log.warn("missing confirmation for formatting of filesystem: %s" % self.device)
				self.hdf["Data.Warning"] = "Plugins.volume_format_fs.FormatNotConfirmed"
				return "volume_format"
			if container_type == "luks":
				return "volume_format_luks"
			elif container_type == "plain":
				return self.__format_plain(fs_type)
		elif store == "step2":
			if container_type == "luks":
				return self.__format_luks(fs_type, crypto_password, crypto_password2)
			else:
				self.cbox.log.info("invalid input value for 'container_type': %s" % container_type)
				return "volume_format"
		elif store:
			self.cbox.log.info("invalid input value for 'store': %s" % store)
			return "volume_format"
		else:
			return "volume_format"


	def getStatus(self):
		return "no status"


	def __format_plain(self, fsType):
		try:
			container = self.cbox.getContainer(self.device)
			container.create(container.Types["plain"])
		except CBVolumeIsActive:
			self.hdf["Data.Warning"] = "VolumeMayNotBeMounted"
			self.cbox.log.info("initialization is not possible as long as the device (%s) is mounted" % self.device)
			return None
		except CBContainerError, errMsg:
			self.hdf["Data.Warning"] = "Plugins.volume_format_fs.FormatFailed"
			self.cbox.log.warn("initialization of device '%s' failed" % self.device)
			self.cbox.log.warn("reason: %s" % errMsg)
			return "volume_format"
		else:
			self.cbox.log.info("successfully initialized device '%s'" % self.device)
			return None


	def __format_luks(self, fsType, pw, pw2):
		if not pw:
			self.hdf["Data.Warning"] = "EmptyPassword"
			self.cbox.log.warn("no crypto password was supplied for initialization of device '%s'" % self.device)
			return "volume_format"
		if pw != pw2:
			self.hdf["Data.Warning"] = "DifferentPasswords"
			self.cbox.log.warn("the crypto password was not repeated correctly for initialization of device '%s'" % self.device)
			return "volume_format"
		container = self.cbox.getContainer(self.device)
		try:
			container.create(container.Types["luks"], pw)
		except CBVolumeIsActive:
			self.hdf["Data.Warning"] = "VolumeMayNotBeMounted"
			self.cbox.log.info("initialization is not possible as long as the device (%s) is mounted" % self.device)
			return None
		except CBContainerError, errMsg:
			self.hdf["Data.Warning"] = "Plugins.volume_format_fs.FormatFailed"
			self.cbox.log.warn("initialization of device '%s' failed" % self.device)
			self.cbox.log.warn("reason: %s" % errMsg)
			return "volume_format"
		else:
			self.hdf["Data.Success"] = "Plugins.volume_format_fs.FormatSuccess"
			self.cbox.log.info("successfully initialized device '%s'" % self.device)
			return None

