#!/usr/bin/python -b
# Copyright 2013-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import argparse
import os
import stat
import sys
import subprocess
import traceback

import portage
from portage.util.movefile import _copyxattr
from portage.exception import OperationNotSupported

# Change back to original cwd _after_ all imports (bug #469338).
os.chdir(os.environ["__PORTAGE_HELPER_CWD"])

def parse_args(args):
	"""
	Parse the command line arguments using optparse for python 2.6 compatibility
	Args:
	  args: a list of the white space delimited command line
	Returns:
	  tuple of the Namespace of parsed options, and a list of order parameters
	"""
	parser = argparse.ArgumentParser(add_help=False)

	parser.add_argument(
		"-b",
		action="store_true",
		dest="shortopt_b"
	)
	parser.add_argument(
		"--backup",
		action="store",
		dest="backup"
		)
	parser.add_argument(
		"-c",
		action="store_true",
		dest="shortopt_c"
	)
	parser.add_argument(
		"--compare",
		"-C",
		action="store_true",
		dest="compare"
	)
	parser.add_argument(
		"--directory",
			"-d",
		action="store_true",
		dest="directory"
	)
	parser.add_argument(
		"-D",
		action="store_true",
		dest="shortopt_D"
	)
	parser.add_argument(
		"--owner",
		"-o",
		action="store",
		dest="owner"
	)
	parser.add_argument(
		"--group",
		"-g",
		action="store",
		dest="group"
	)
	parser.add_argument(
		"--mode",
		"-m",
		action="store",
		dest="mode"
	)
	parser.add_argument(
		"--preserve-timestamps",
		"-p",
		action="store_true",
		dest="preserve_timestamps"
	)
	parser.add_argument(
		"--strip",
		"-s",
		action="store_true",
		dest="strip"
	)
	parser.add_argument(
		"--strip-program",
		action="store",
		dest="strip_program"
	)
	parser.add_argument(
		"--suffix",
		"-S",
		action="store",
		dest="suffix"
	)
	parser.add_argument(
		"--target-directory",
		"-t",
		action="store",
		dest="target_directory"
	)
	parser.add_argument(
		"--no-target-directory",
		"-T",
		action="store_true",
		dest="no_target_directory"
	)
	parser.add_argument(
		"--context",
		"-Z",
		action="store",
		dest="context"
	)
	parser.add_argument(
		"--verbose",
		"-v",
		action="store_true",
		dest="verbose"
	)
	parser.add_argument(
		"--help",
		action="store_true",
		dest="help"
	)
	parser.add_argument(
		"--version",
		action="store_true",
		dest="version"
	)

	# Use parse_known_args for maximum compatibility with
	# getopt handling of non-option file arguments. Note
	# that parser.add_argument("files", nargs='+') would
	# be subtly incompatible because it requires that all
	# of the file arguments be grouped sequentially. Also
	# note that we have to explicitly call add_argument
	# for known options in order for argparse to correctly
	# separate option arguments from file arguments in all
	# cases (it also allows for optparse compatibility).
	parsed_args = parser.parse_known_args()

	opts  = parsed_args[0]
	files = parsed_args[1]
	files = [f for f in files if f != "--"]	# filter out "--"

	return (opts, files)


def copy_xattrs(opts, files):
	"""
	Copy the extended attributes using portage.util.movefile._copyxattr
	Args:
	  opts:  Namespace of the parsed command line otions
	  files: list of ordered command line parameters which should be files/directories
	Returns:
	  system exit code
	"""
	if opts.directory or not files:
		return os.EX_OK

	if opts.target_directory is None:
		source, target = files[:-1], files[-1]
		target_is_directory = os.path.isdir(target)
	else:
		source, target = files, opts.target_directory
		target_is_directory = True

	exclude = os.environ.get("PORTAGE_XATTR_EXCLUDE", "")

	try:
		if target_is_directory:
			for s in source:
				abs_path = os.path.join(target, os.path.basename(s))
				_copyxattr(s, abs_path, exclude=exclude)
		else:
			_copyxattr(source[0], target, exclude=exclude)
		return os.EX_OK

	except OperationNotSupported:
		traceback.print_exc()
		return os.EX_OSERR


def Which(filename, path=None, exclude=None):
	"""
	Find the absolute path of 'filename' in a given search 'path'
	Args:
	  filename: basename of the file
	  path: colon delimited search path
	  exclude: path of file to exclude
	"""
	if path is None:
		path = os.environ.get('PATH', '')

	if exclude is not None:
		st = os.stat(exclude)
		exclude = (st.st_ino, st.st_dev)

	for p in path.split(':'):
		p = os.path.join(p, filename)
		if os.access(p, os.X_OK):
			try:
				st = os.stat(p)
			except OSError:
				# file disappeared?
				pass
			else:
				if stat.S_ISREG(st.st_mode) and \
					(exclude is None or exclude != (st.st_ino, st.st_dev)):
					return p

	return None


def main(args):
	opts, files = parse_args(args)
	install_binary = Which('install', exclude=os.environ["__PORTAGE_HELPER_PATH"])
	if install_binary is None:
		sys.stderr.write("install: command not found\n")
		return 127

	cmdline = [install_binary]
	cmdline += args

	if sys.hexversion >= 0x3000000:
		# We can't trust that the filesystem encoding (locale dependent)
		# correctly matches the arguments, so use surrogateescape to
		# pass through the original argv bytes for Python 3.
		fs_encoding = sys.getfilesystemencoding()
		cmdline = [x.encode(fs_encoding, 'surrogateescape') for x in cmdline]
		files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
		if opts.target_directory is not None:
			opts.target_directory = \
				opts.target_directory.encode(fs_encoding, 'surrogateescape')

	returncode = subprocess.call(cmdline)
	if returncode == os.EX_OK:
		returncode = copy_xattrs(opts, files)
		if returncode != os.EX_OK:
			portage.util.writemsg("!!! install: copy_xattrs failed with the "
				"following arguments: %s\n" %
				" ".join(portage._shell_quote(x) for x in args), noiselevel=-1)
	return returncode


if __name__ == "__main__":
	sys.exit(main(sys.argv[1:]))
