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

import io
import os
import sys
import textwrap

try:
	from urllib.parse import urlparse
except ImportError:
	from urlparse import urlparse

from os import path as osp
pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
sys.path.insert(0, pym_path)
import portage
portage._internal_caller = True
from portage.util._argparse import ArgumentParser

def parse_args(argv):
	prog_name = os.path.basename(argv[0])
	usage = prog_name + ' [options] ' + \
		'<src_pkg_dir> <snapshot_dir> <snapshot_uri> <binhost_dir>'

	prog_desc = "This program will copy src_pkg_dir to snapshot_dir " + \
		"and inside binhost_dir it will create a Packages index file " + \
		"which refers to snapshot_uri. This is intended to solve race " + \
		"conditions on binhosts as described at http://crosbug.com/3225."

	usage += "\n\n"
	for line in textwrap.wrap(prog_desc, 70):
		usage += line + "\n"

	usage += "\n"
	usage += "Required Arguments:\n\n"
	usage += "  src_pkg_dir  - the source $PKGDIR\n"
	usage += "  snapshot_dir - destination snapshot " + \
		"directory (must not exist)\n"
	usage += "  snapshot_uri - URI which refers to " + \
		"snapshot_dir from the\n" + \
		"                 client side\n"
	usage += "  binhost_dir  - directory in which to " + \
		"write Packages index with\n" + \
		"                 snapshot_uri"

	parser = ArgumentParser(usage=usage)
	parser.add_argument('--hardlinks',
		help='create hardlinks (y or n, default is y)',
		choices=('y', 'n'),
		default='y')
	options, args = parser.parse_known_args(argv[1:])

	if len(args) != 4:
		parser.error("Required 4 arguments, got %d" % (len(args),))

	return parser, options, args

def main(argv):
	parser, options, args = parse_args(argv)

	src_pkg_dir, snapshot_dir, snapshot_uri, binhost_dir = args
	src_pkgs_index = os.path.join(src_pkg_dir, 'Packages')

	if not os.path.isdir(src_pkg_dir):
		parser.error("src_pkg_dir is not a directory: '%s'" % (src_pkg_dir,))

	if not os.path.isfile(src_pkgs_index):
		parser.error("src_pkg_dir does not contain a " + \
			"'Packages' index: '%s'" % (src_pkg_dir,))

	parse_result = urlparse(snapshot_uri)
	if not (parse_result.scheme and parse_result.netloc and parse_result.path):
		parser.error("snapshot_uri is not a valid URI: '%s'" % (snapshot_uri,))

	if os.path.isdir(snapshot_dir):
		parser.error("snapshot_dir already exists: '%s'" % snapshot_dir)

	try:
		os.makedirs(os.path.dirname(snapshot_dir))
	except OSError:
		pass
	if not os.path.isdir(os.path.dirname(snapshot_dir)):
		parser.error("snapshot_dir parent could not be created: '%s'" % \
			os.path.dirname(snapshot_dir))

	try:
		os.makedirs(binhost_dir)
	except OSError:
		pass
	if not os.path.isdir(binhost_dir):
		parser.error("binhost_dir could not be created: '%s'" % binhost_dir)

	cp_opts = 'RP'
	if options.hardlinks == 'n':
		cp_opts += 'p'
	else:
		cp_opts += 'l'

	cp_cmd = 'cp -%s %s %s' % (
		cp_opts,
		portage._shell_quote(src_pkg_dir),
		portage._shell_quote(snapshot_dir)
	)

	ret = os.system(cp_cmd)
	if not (os.WIFEXITED(ret) and os.WEXITSTATUS(ret) == os.EX_OK):
		return 1

	infile = io.open(portage._unicode_encode(src_pkgs_index,
		encoding=portage._encodings['fs'], errors='strict'),
		mode='r', encoding=portage._encodings['repo.content'],
		errors='strict')

	outfile = portage.util.atomic_ofstream(
		os.path.join(binhost_dir, "Packages"),
		encoding=portage._encodings['repo.content'],
		errors='strict')

	for line in infile:
		if line[:4] == 'URI:':
			# skip existing URI line
			pass
		else:
			if not line.strip():
				# end of header
				outfile.write("URI: %s\n\n" % snapshot_uri)
				break
			outfile.write(line)

	for line in infile:
		outfile.write(line)

	infile.close()
	outfile.close()

	return os.EX_OK

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