# -*- coding:utf-8 -*-


import io
import logging
import re
import sys
import textwrap

# import our initialized portage instance
from repoman._portage import portage

from portage import os
from portage import _encodings
from portage import _unicode_encode

from repoman.errors import err
from repoman.profile import ProfileDesc, valid_profile_types

GPG_KEY_ID_REGEX = r'(0x)?([0-9a-fA-F]{8}){1,5}!?'
bad = portage.output.create_color_func("BAD")


class RepoSettings(object):
	'''Holds our repo specific settings'''

	def __init__(
		self, config_root, portdir, portdir_overlay,
		repoman_settings=None, vcs_settings=None, options=None,
		qawarnings=None):
		self.config_root = config_root
		self.repoman_settings = repoman_settings
		self.vcs_settings = vcs_settings

		self.repositories = self.repoman_settings.repositories

		# Ensure that current repository is in the list of enabled repositories.
		self.repodir = os.path.realpath(portdir_overlay)
		try:
			self.repositories.get_repo_for_location(self.repodir)
		except KeyError:
			self._add_repo(config_root, portdir_overlay)

		self.root = self.repoman_settings['EROOT']
		self.trees = {
			self.root: {'porttree': portage.portagetree(settings=self.repoman_settings)}
		}
		self.portdb = self.trees[self.root]['porttree'].dbapi

		# Constrain dependency resolution to the master(s)
		# that are specified in layout.conf.
		self.repo_config = self.repositories.get_repo_for_location(self.repodir)
		self.portdb.porttrees = list(self.repo_config.eclass_db.porttrees)
		self.portdir = self.portdb.porttrees[0]
		self.commit_env = os.environ.copy()
		# list() is for iteration on a copy.
		for repo in list(self.repositories):
			# all paths are canonical
			if repo.location not in self.repo_config.eclass_db.porttrees:
				del self.repositories[repo.name]

		if self.repo_config.allow_provide_virtual:
			qawarnings.add("virtual.oldstyle")

		if self.repo_config.sign_commit and options.mode in ("commit", "fix", "manifest"):
			if vcs_settings.vcs:
				func = getattr(self, '_vcs_gpg_%s' % vcs_settings.vcs)
				func()
			else:
				logging.warning("No VCS type detected, unable to sign the commit")

		# In order to disable manifest signatures, repos may set
		# "sign-manifests = false" in metadata/layout.conf. This
		# can be used to prevent merge conflicts like those that
		# thin-manifests is designed to prevent.
		self.sign_manifests = "sign" in self.repoman_settings.features and \
			self.repo_config.sign_manifest

		if self.repo_config.sign_manifest and self.repo_config.name == "gentoo" and \
			options.mode in ("commit",) and not self.sign_manifests:
			msg = (
				"The '%s' repository has manifest signatures enabled, "
				"but FEATURES=sign is currently disabled. In order to avoid this "
				"warning, enable FEATURES=sign in make.conf. Alternatively, "
				"repositories can disable manifest signatures by setting "
				"'sign-manifests = false' in metadata/layout.conf.") % (
					self.repo_config.name,)
			for line in textwrap.wrap(msg, 60):
				logging.warn(line)

		is_commit = options.mode in ("commit",)
		valid_gpg_key = self.repoman_settings.get("PORTAGE_GPG_KEY") and re.match(
			r'^%s$' % GPG_KEY_ID_REGEX, self.repoman_settings["PORTAGE_GPG_KEY"])

		if self.sign_manifests and is_commit and not valid_gpg_key:
			logging.error(
				"PORTAGE_GPG_KEY value is invalid: %s" %
				self.repoman_settings["PORTAGE_GPG_KEY"])
			sys.exit(1)

		manifest_hashes = self.repo_config.manifest_hashes
		if manifest_hashes is None:
			manifest_hashes = portage.const.MANIFEST2_HASH_DEFAULTS

		if options.mode in ("commit", "fix", "manifest"):
			if portage.const.MANIFEST2_REQUIRED_HASH not in manifest_hashes:
				msg = (
					"The 'manifest-hashes' setting in the '%s' repository's "
					"metadata/layout.conf does not contain the '%s' hash which "
					"is required by this portage version. You will have to "
					"upgrade portage if you want to generate valid manifests for "
					"this repository.") % (
					self.repo_config.name, portage.const.MANIFEST2_REQUIRED_HASH)
				for line in textwrap.wrap(msg, 70):
					logging.error(line)
				sys.exit(1)

			unsupported_hashes = manifest_hashes.difference(
				portage.const.MANIFEST2_HASH_FUNCTIONS)
			if unsupported_hashes:
				msg = (
					"The 'manifest-hashes' setting in the '%s' repository's "
					"metadata/layout.conf contains one or more hash types '%s' "
					"which are not supported by this portage version. You will "
					"have to upgrade portage if you want to generate valid "
					"manifests for this repository.") % (
					self.repo_config.name, " ".join(sorted(unsupported_hashes)))
				for line in textwrap.wrap(msg, 70):
					logging.error(line)
				sys.exit(1)

	def _add_repo(self, config_root, portdir_overlay):
		self.repo_conf = portage.repository.config
		self.repo_name = self.repo_conf.RepoConfig._read_valid_repo_name(
			portdir_overlay)[0]
		self.layout_conf_data = self.repo_conf.parse_layout_conf(portdir_overlay)[0]
		if self.layout_conf_data['repo-name']:
			self.repo_name = self.layout_conf_data['repo-name']
		tmp_conf_file = io.StringIO(textwrap.dedent("""
			[%s]
			location = %s
			""") % (self.repo_name, portdir_overlay))
		# Ensure that the repository corresponding to $PWD overrides a
		# repository of the same name referenced by the existing PORTDIR
		# or PORTDIR_OVERLAY settings.
		self.repoman_settings['PORTDIR_OVERLAY'] = "%s %s" % (
			self.repoman_settings.get('PORTDIR_OVERLAY', ''),
			portage._shell_quote(portdir_overlay))
		self.repositories = self.repo_conf.load_repository_config(
			self.repoman_settings, extra_files=[tmp_conf_file])
		# We have to call the config constructor again so that attributes
		# dependent on config.repositories are initialized correctly.
		self.repoman_settings = portage.config(
			config_root=config_root, local_config=False,
			repositories=self.repositories)

	##########
	# future vcs plugin functions
	##########

	def _vcs_gpg_bzr(self):
		pass

	def _vcs_gpg_cvs(self):
		pass

	def _vcs_gpg_git(self):
		# NOTE: It's possible to use --gpg-sign=key_id to specify the key in
		# the commit arguments. If key_id is unspecified, then it must be
		# configured by `git config user.signingkey key_id`.
		self.vcs_settings.vcs_local_opts.append("--gpg-sign")
		if self.repoman_settings.get("PORTAGE_GPG_DIR"):
			# Pass GNUPGHOME to git for bug #462362.
			self.commit_env["GNUPGHOME"] = self.repoman_settings["PORTAGE_GPG_DIR"]

		# Pass GPG_TTY to git for bug #477728.
		try:
			self.commit_env["GPG_TTY"] = os.ttyname(sys.stdin.fileno())
		except OSError:
			pass

	def _vcs_gpg_hg(self):
		pass

	def _vcs_gpg_svn(self):
		pass


def list_checks(kwlist, liclist, uselist, repoman_settings):
	liclist_deprecated = set()
	if "DEPRECATED" in repoman_settings._license_manager._license_groups:
		liclist_deprecated.update(
			repoman_settings._license_manager.expandLicenseTokens(["@DEPRECATED"]))

	if not liclist:
		logging.fatal("Couldn't find licenses?")
		sys.exit(1)

	if not kwlist:
		logging.fatal("Couldn't read KEYWORDS from arch.list")
		sys.exit(1)

	if not uselist:
		logging.fatal("Couldn't find use.desc?")
		sys.exit(1)
	return liclist_deprecated


def repo_metadata(portdb, repoman_settings):
	# get lists of valid keywords, licenses, and use
	kwlist = set()
	liclist = set()
	uselist = set()
	profile_list = []
	global_pmasklines = []

	for path in portdb.porttrees:
		try:
			liclist.update(os.listdir(os.path.join(path, "licenses")))
		except OSError:
			pass
		kwlist.update(
			portage.grabfile(os.path.join(path, "profiles", "arch.list")))

		use_desc = portage.grabfile(os.path.join(path, 'profiles', 'use.desc'))
		for x in use_desc:
			x = x.split()
			if x:
				uselist.add(x[0])

		expand_desc_dir = os.path.join(path, 'profiles', 'desc')
		try:
			expand_list = os.listdir(expand_desc_dir)
		except OSError:
			pass
		else:
			for fn in expand_list:
				if not fn[-5:] == '.desc':
					continue
				use_prefix = fn[:-5].lower() + '_'
				for x in portage.grabfile(os.path.join(expand_desc_dir, fn)):
					x = x.split()
					if x:
						uselist.add(use_prefix + x[0])

		global_pmasklines.append(
			portage.util.grabfile_package(
				os.path.join(path, 'profiles', 'package.mask'),
				recursive=1, verify_eapi=True))

		desc_path = os.path.join(path, 'profiles', 'profiles.desc')
		try:
			desc_file = io.open(
				_unicode_encode(
					desc_path, encoding=_encodings['fs'], errors='strict'),
				mode='r', encoding=_encodings['repo.content'], errors='replace')
		except EnvironmentError:
			pass
		else:
			for i, x in enumerate(desc_file):
				if x[0] == "#":
					continue
				arch = x.split()
				if len(arch) == 0:
					continue
				if len(arch) != 3:
					err(
						"wrong format: \"%s\" in %s line %d" %
						(bad(x.strip()), desc_path, i + 1, ))
				elif arch[0] not in kwlist:
					err(
						"invalid arch: \"%s\" in %s line %d" %
						(bad(arch[0]), desc_path, i + 1, ))
				elif arch[2] not in valid_profile_types:
					err(
						"invalid profile type: \"%s\" in %s line %d" %
						(bad(arch[2]), desc_path, i + 1, ))
				profile_desc = ProfileDesc(arch[0], arch[2], arch[1], path)
				if not os.path.isdir(profile_desc.abs_path):
					logging.error(
						"Invalid %s profile (%s) for arch %s in %s line %d",
						arch[2], arch[1], arch[0], desc_path, i + 1)
					continue
				if os.path.exists(
					os.path.join(profile_desc.abs_path, 'deprecated')):
					continue
				profile_list.append(profile_desc)
			desc_file.close()

	global_pmasklines = portage.util.stack_lists(global_pmasklines, incremental=1)
	global_pmaskdict = {}
	for x in global_pmasklines:
		global_pmaskdict.setdefault(x.cp, []).append(x)
	del global_pmasklines

	return (
		kwlist, liclist, uselist, profile_list, global_pmaskdict,
		list_checks(kwlist, liclist, uselist, repoman_settings))
