# Copyright 2005-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Author(s): Brian Harring (ferringb@gentoo.org)

import os as _os
import sys
from portage.cache import template
from portage import os

from portage.proxy.lazyimport import lazyimport
lazyimport(globals(),
	'portage.exception:PortageException',
	'portage.util:apply_permissions',
)
del lazyimport

if sys.hexversion >= 0x3000000:
	# pylint: disable=W0622
	long = int

class FsBased(template.database):
	"""template wrapping fs needed options, and providing _ensure_access as a way to 
	attempt to ensure files have the specified owners/perms"""

	def __init__(self, *args, **config):

		for x, y in (("gid", -1), ("perms", -1)):
			if x in config:
				# Since Python 3.4, chown requires int type (no proxies).
				setattr(self, "_" + x, int(config[x]))
				del config[x]
			else:
				setattr(self, "_"+x, y)
		super(FsBased, self).__init__(*args, **config)

		if self.label.startswith(os.path.sep):
			# normpath.
			self.label = os.path.sep + os.path.normpath(self.label).lstrip(os.path.sep)


	def _ensure_access(self, path, mtime=-1):
		"""returns true or false if it's able to ensure that path is properly chmod'd and chowned.
		if mtime is specified, attempts to ensure that's correct also"""
		try:
			apply_permissions(path, gid=self._gid, mode=self._perms)
			if mtime != -1:
				mtime=long(mtime)
				os.utime(path, (mtime, mtime))
		except (PortageException, EnvironmentError):
			return False
		return True

	def _ensure_dirs(self, path=None):
		"""with path!=None, ensure beyond self.location.  otherwise, ensure self.location"""
		if path:
			path = os.path.dirname(path)
			base = self.location
		else:
			path = self.location
			base='/'

		for dir in path.lstrip(os.path.sep).rstrip(os.path.sep).split(os.path.sep):
			base = os.path.join(base,dir)
			if not os.path.exists(base):
				if self._perms != -1:
					um = os.umask(0)
				try:
					perms = self._perms
					if perms == -1:
						perms = 0
					perms |= 0o755
					os.mkdir(base, perms)
					if self._gid != -1:
						os.chown(base, -1, self._gid)
				finally:
					if self._perms != -1:
						os.umask(um)

	def _prune_empty_dirs(self):
		all_dirs = []
		for parent, dirs, files in os.walk(self.location):
			for x in dirs:
				all_dirs.append(_os.path.join(parent, x))
		while all_dirs:
			try:
				_os.rmdir(all_dirs.pop())
			except OSError:
				pass

def gen_label(base, label):
	"""if supplied label is a path, generate a unique label based upon label, and supplied base path"""
	if label.find(os.path.sep) == -1:
		return label
	label = label.strip("\"").strip("'")
	label = os.path.join(*(label.rstrip(os.path.sep).split(os.path.sep)))
	tail = os.path.split(label)[1]
	return "%s-%X" % (tail, abs(label.__hash__()))

