"""
Common functionality for the DC user interface.
"""

#c Copyright 2008-2025, the GAVO project <gavo@ari.uni-heidelberg.de>
#c
#c This program is free software, covered by the GNU GPL.  See the
#c COPYING file in the source distribution.


import sys


def getMatchingFunction(funcSelector, functions, parser):
	"""returns the module name and a function name within the module for
	the function selector funcSelector.

	The function will exit if funcSelector is not a unique prefix within
	functions.
	"""
	matches = []
	for key, res in functions:
		if key.startswith(funcSelector):
			matches.append(res)
	if len(matches)==1:
		return matches[0]
	if matches:
		sys.stderr.write("Multiple matches for function %s.\n\n"%funcSelector)
	else:
		sys.stderr.write("No match for function %s.\n\n"%funcSelector)
	parser.print_help(file=sys.stderr)
	sys.exit(1)


def _getAutoDDIds(rd):
	"""helps getPertainingDDs
	"""
	res = []
	for dd in rd.dds:
		if dd.auto:
			res.append(dd)
	return res


def _getSelectedDDIds(rd, selectedIds):
	"""helps getPertainingDDs
	"""
	res = []
	ddDict = dict((dd.id, dd) for dd in rd.dds)
	for ddId in selectedIds:
		if ddId not in ddDict:
			from gavo import base
			raise base.ReportableError(
				"The DD '%s' you are trying to import is not defined within"
				" the RD '%s'."%(ddId, rd.sourceId),
				hint="Data elements available in %s include %s"%(rd.sourceId,
					", ".join(ddDict) or '(None)'))
		res.append(ddDict[ddId])
	return res


def getPertainingDDs(rd, selectedIds):
	"""returns a list of dds on which imp or drop should operate.

	By default, that's the "auto" dds of rd.  If ddIds is not empty,
	it is validated that all ids mentioned actually exist.

	Finally, if no DDs are selected but DDs are available, an error is raised.
	"""
	if selectedIds:
		dds = _getSelectedDDIds(rd, selectedIds)
	else:
		dds = _getAutoDDIds(rd)
	if not dds:
		if not rd.dds:
			from gavo import base
			base.ui.notifyWarning("There is no data element"
				" in the RD %s; is that all right?"%rd.sourceId)
		else:
			from gavo import base
			raise base.ReportableError(
				"Neither automatic not manual data selected from RD %s "%rd.sourceId,
				hint="All data elements have auto=False.  You have to"
					" explicitly name one or more data to import (names"
					" available: %s)"%(", ".join(dd.id or "(anon)" for dd in rd.dds)))
	return dds



