import os
import commands
from PlatformObjects import VolumeRepresentation, Mtab
import re
# FIXME these are mostly stubs, no more

_blkid_datum_regexp = re.compile('(\w+)="(.+?)"')
_network_fstypes = "nfs","smbfs","autofs","autofs4","ncpfs","smb","coda","afs"

def is_executable(command):
	if os.access(command,os.X_OK): return True
	path = os.environ["PATH"].split(":")
	for direct in path:
		if os.access(os.path.join(direct,command),os.X_OK): return True
	return False

if not is_executable("/sbin/blkid"): raise ImportError, "Required command /sbin/blkid is not available"

def get_currently_known_volumes():
	""" returns a dictionary of volumes, keyed by GUID.  Each volume is a struct VolumeRepresentation, with GUID, currently known device file, filesystem type, and volume label information."""
	output = commands.getoutput("/sbin/blkid")
	volumes = {}
	for line in output.splitlines():
		dline = line.split(':',2)
		datums = _blkid_datum_regexp.findall(dline[1].strip())
		data = VolumeRepresentation()
		data.current_device_file = dline[0]
		data.removable = False # STUB!!!!! need to be fixed for cdroms and shit FIXME
		data.loop_mounted = data.current_device_file.startswith("/dev/loop")
		for datum in datums:
			key = datum[0]; value = datum[1]
			if key == "TYPE":
				data.filesystem_type = value
				if data.filesystem_type in _network_fstypes:
					data.network_volume = True
			if key == "UUID": data.guid = value
			if key == "LABEL": data.label = value
		if data.guid:	# this covers the famous devfs, swap, procfs and rpc_pipefs,
					# sysfs cases in a very handsome fashion, yippeeeee
			volumes[data.guid] = data
	return volumes


def get_mtab():
	""" return the mtab as a list of lists """
# 	import csv
# 	
# 	class MtabDialect(csv.Dialect):
# 	
# 		delimiter = " "
# 		lineterminator = "\n"
# 		escapechar = '\\'
# 		skipinitialspace = True
# 		doublequote = True
# 		quotechar = ' '
# 		quoting = csv.QUOTE_NONE
	
	f = file("/etc/mtab","r")
	mtablines = f.readlines()
	f.close()
	
	mtablines = [ line.split(" ") for line in mtablines ]
	
	mtab = Mtab()
	
	for a in mtablines:
		mtab.add_record(a[0].decode("string_escape"),a[1].decode("string_escape"),
						a[2],a[3],a[4],a[5])
	return mtab


def strip_mountpoint(filename,mountpoint):
	filename = os.path.normpath(filename)
	mountpoint = os.path.normpath(mountpoint)
# 	if not mountpoint.startswith(mountpoint): raise RuntimeError, "%s not in %s"%(filename,mountpoint)
	while mountpoint.endswith("/"): mountpoint = mountpoint[:-1]
	filename =  filename[len(mountpoint)+1:]
	return filename

def _canonicalize_path(path):
	path = os.path.normpath(path)
# 	while path.endswith("/"): path = path[:-1]
	if not path.endswith("/"): path = path + "/"
	return path

def is_or_is_below(filename,path):
	""" Tests whether filename is the same as path or is below path """
	filename = _canonicalize_path(filename)
	path = _canonicalize_path(path)
	return filename.startswith(path)

from MetadataService.common import shell_quote
def get_mimetype(filename):
	if os.path.isdir(filename): return "inode/directory"
	output = commands.getoutput("file -bi %s"%shell_quote(filename))
	if output.startswith("cannot"): return None
	mimetype = output.split(";",2)[0].strip()
	if len(mimetype) > 0: return mimetype
	
	
