# Temporary file name allocation
#
# XXX This tries to be not UNIX specific, but I don't know beans about
# how to choose a temp directory or filename on MS-DOS or other
# systems so it may have to be changed...


import os


# Parameters that the caller may set to override the defaults

tempdir = None
template = None


# Function to calculate the directory to use

def gettempdir():
    global tempdir
    if tempdir is not None:
	return tempdir
    attempdirs = ['/usr/tmp', '/tmp', os.getcwd(), os.curdir]
    if os.name == 'nt':
	attempdirs.insert(0, 'C:\\TEMP')
	attempdirs.insert(0, '\\TEMP')
    elif os.name == 'mac':
    	import macfs, MACFS
    	try:
    	     refnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk,
					      MACFS.kTemporaryFolderType, 0)
    	     dirname = macfs.FSSpec((refnum, dirid, '')).as_pathname()
    	     attempdirs.insert(0, dirname)
	except macfs.error:
	    pass
    for envname in 'TMPDIR', 'TEMP', 'TMP':
	if os.environ.has_key(envname):
	    attempdirs.insert(0, os.environ[envname])
    testfile = gettempprefix() + 'test'
    for dir in attempdirs:
	try:
	    filename = os.path.join(dir, testfile)
	    fp = open(filename, 'w')
	    fp.write('blat')
	    fp.close()
	    os.unlink(filename)
	    tempdir = dir
	    break
	except IOError:
	    pass
    if tempdir is None:
	msg = "Can't find a usable temporary directory amongst " + `attempdirs`
	raise IOError, msg
    return tempdir


# Function to calculate a prefix of the filename to use

def gettempprefix():
	global template
	if template == None:
		if os.name == 'posix':
			template = '@' + `os.getpid()` + '.'
		elif os.name == 'nt':
			template = '~' + `os.getpid()` + '-'
		elif os.name == 'mac':
			template = 'Python-Tmp-'
		else:
			template = 'tmp' # XXX might choose a better one
	return template


# Counter for generating unique names

counter = 0


# User-callable function to return a unique temporary file name

def mktemp(suffix=""):
	global counter
	dir = gettempdir()
	pre = gettempprefix()
	while 1:
		counter = counter + 1
		file = os.path.join(dir, pre + `counter` + suffix)
		if not os.path.exists(file):
			return file


class TemporaryFileWrapper:
    """Temporary file wrapper

    This class provides a wrapper around files opened for temporary use.
    In particular, it seeks to automatically remove the file when it is
    no longer needed.
    """
    def __init__(self, file, path):
	self.file = file
	self.path = path

    def close(self):
	self.file.close()
	os.unlink(self.path)

    def __del__(self):
	try: self.close()
	except: pass

    def __getattr__(self, name):
	file = self.__dict__['file']
	a = getattr(file, name)
	setattr(self, name, a)
	return a


def TemporaryFile(mode='w+b', bufsize=-1, suffix=""):
    name = mktemp(suffix)
    file = open(name, mode, bufsize)
    try:
	os.unlink(name)
    except os.error:
	# Non-unix -- can't unlink file that's still open, use wrapper
	return TemporaryFileWrapper(file, name)
    else:
	return file
