import posixpath
from pipes import quote


def is_debian(runner):
	result = runner.run("/bin/sh", ["-c", '/usr/bin/test -f /etc/debian_version && echo "yes" || echo "no"']).strip()
	if result == "yes":
		return True
	elif result == "no":
		return False
	else:
		raise Exception(u"Failed to detect OS: invalid output '%s'" % (result,))


def is_centos(runner):
	result = runner.run("/bin/sh", ["-c", '/usr/bin/test -f /etc/redhat-release && echo "yes" || echo "no"']).strip()
	if result == "yes":
		return True
	elif result == "no":
		return False
	else:
		raise Exception(u"Failed to detect OS: invalid output '%s'" % (result,))


def is_suse(runner):
	result = runner.run("/bin/sh", ["-c", '/usr/bin/test -f /etc/SuSE-release && echo "yes" || echo "no"']).strip()
	if result == "yes":
		return True
	elif result == "no":
		return False
	else:
		raise Exception(u"Failed to detect OS: invalid output '%s'" % (result,))


def map_copy_owner_user(runner_source, runner_target, source_basedir, target_basedir, owner_from, owner_to):
	"""For each file on source node located in 'source_basedir' and owned by user 'owner_from' 
	change user to 'owner_to' on target node in 'target_basedir'"""
	_map_copy_owner(
		runner_source, runner_target, source_basedir, target_basedir, owner_from, owner_to, "user", "/bin/chown"
	)


def map_copy_owner_group(runner_source, runner_target, source_basedir, target_basedir, owner_from, owner_to):
	"""For each file on source node located in 'source_basedir' and owned by group 'owner_from' 
	change group to 'owner_to' on target node in 'target_basedir'"""
	_map_copy_owner(
		runner_source, runner_target, source_basedir, target_basedir, owner_from, owner_to, "group", "/bin/chgrp"
	)


def _map_copy_owner(
	runner_source, runner_target, source_basedir, target_basedir, owner_from, owner_to, find_criteria, change_command
):
	filenames = [
		filename for filename in runner_source.run(
			'/usr/bin/find', [source_basedir, '-%s' % (find_criteria,), owner_from, '-printf', r'%P\n']
		).splitlines() 
		if filename != ''
	]
	for filename in filenames:
		target_filename = posixpath.join(target_basedir, filename)
		if file_exists(runner_target, target_filename):
			runner_target.run(
				change_command, [owner_to, target_filename]
			)


def format_command(template, *args, **kw):
	qargs = map(quote, args)
	qkw = dict((k, quote(unicode(v))) for k, v in kw.iteritems())
	return unicode(template).format(*qargs, **qkw)


def format_command_list(cmd, args):
	return " ".join([
		quote(arg) for arg in [cmd] + ([] if args is None else args)
	])


def file_exists(runner, filepath):
	exit_code, _, _ = runner.run_unchecked('/usr/bin/test', ['-e', filepath])
	return exit_code == 0


def get_files_list(runner, path):
	files = runner.sh('find {path}/* -maxdepth 0 -type f -printf "%f\\0"'.format(path=path)).split("\0")
	return [item for item in files if item]
