# apfscore adapted to work on Gaia DR2 objects.

import re

from gavo import api
from gavo import base

apfscore, _ = api.loadPythonModule("apfscore", relativeTo=__file__)


class Core(apfscore.BaseCore):
	inputTableXML = apfscore.INPUT_TABLE_XML_TEMPLATE.format(
		objectDescription="Enter a (decimal, comma-separated) position"
			" or simbad identifier to use the closest Gaia DR3 star in the"
			" given magnitude bracket; or use a DR3 source_id (in which case"
			" the magnitude bracket is ignored).",
		objectDefault="23.1, 42.5</property></inputKey>"
			' <inputKey name="minmag" tablehead="Min. mag"'
			'   unit="mag" multiplicity="single"'
			'   description="Minimal (brightest) G magnitude desired">'
			'   <property name="defaultForForm">6</property>'
			' </inputKey>'
			' <inputKey name="maxmag" tablehead="Max. mag"'
			'   unit="mag" multiplicity="single"'
			'   description="Maximal (faintest) G magnitude desired">'
			'   <property name="defaultForForm">10')
	sourceCatName = "Gaia DR3"
	sourceCatId = "gaia/q3#dr3lite"
	catalogueEpoch = 2457389.0
	useLegacy = False

	def resolve(self, inputTable):
		ob = inputTable.args["object"]
		try:
			inputTable.args["star"] = int(ob)
			return
		except ValueError:
			# So, it's not a gaia id.  Try other interpretations.
			pass

		try:
			mat = re.match("^[0-9]+$", ob)
			if mat:
				inputTable.args["star"] = ob
				return
			mat = re.match("([0-9.]+),([0-9.+-]+)$", ob)
			if mat:
				ra, dec = [float(v) for v in mat.groups()]
			else:
				ra, dec = base.caches.getSesame("simbad").getPositionFor(ob)
		except (KeyError, ValueError, AttributeError):
			raise api.ui.logOldExc(
				api.ValidationError("%s is neither an %s number nor"
				" a ra,dec position nor an object known by simbad."%(
					repr(ob),
					self.sourceCatName),
				colName="object"))
		
		with api.getTableConn() as conn:
			res = conn.query("select source_id from gaia.edr3lite"
				" where q3c_join(%(ra0)s, %(dec0)s, ra, dec, 0.25)"
				" and phot_g_mean_mag between %(minmag)s and %(maxmag)s"
				" and pmra is not null and pmdec is not null and"
				" parallax is not null"
				" order by q3c_dist(ra, dec, %(ra0)s, %(dec0)s) asc", {
				'ra0': ra, 'dec0': dec,
				'minmag': inputTable.args["minmag"],
				'maxmag': inputTable.args["maxmag"]})
			try:
				inputTable.args["star"] = next(res)[0]
			except StopIteration:
				raise api.ValidationError("No matches for these settings; choose"
					" a wider magnitude range.", "object")

	def query(self, sourceId, inputTable):
		if self.useLegacy:
			raise NotImplementedError("For legacy operations, check out"
				" rev. 9248.")

		with api.getTableConn() as conn:
			return list(
				conn.query("""
					SELECT ra, dec, pmra, pmdec,
						coalesce(parallax,0)/1000.,
						coalesce(radial_velocity, 0)
					FROM gaia.dr3lite WHERE source_id=%(star)s""",
					{"star": sourceId}))[0]
