"""
Tests in the wider vicinity of cone search.
"""

#c Copyright 2008-2023, 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.


from gavo.helpers import testhelpers

from gavo import api
from gavo.helpers import trialhelpers
from gavo.protocols import scs

import tresc


class QueryBuildingTest(testhelpers.VerboseTest,
		metaclass=testhelpers.SamplesBasedAutoTest):
	def _runTest(self, sample):
		tdLit, expected = sample
		td = api.parseFromString(api.TableDef, tdLit)
		self.assertEqual(
			scs.getRadialCondition(td, 10, 13, 1),
			expected)
	
	samples = [
		("""<table id="t" onDisk="True">
				<mixin>//scs#q3cindex</mixin>
				<column name="raj2000" ucd="pos.eq.ra;meta.main"/>
				<column name="dej2000" ucd="pos.eq.dec;meta.main"/>
			</table>""",
			"q3c_radial_query(raj2000, dej2000, 10, 13, 1)"),
		("""<table id="t" onDisk="True">
				<column name="ra" ucd="pos.eq.ra;meta.main"/>
				<column name="dec" ucd="pos.eq.dec;meta.main"/>
			</table>""",
			"spoint(radians(ra), radians(dec))"
			"  <@ scircle(spoint(radians(10), radians(13)), radians(1))"),
		("""<table id="t" onDisk="True" mixin="//scs#pgs-pos-index">
				<column name="quoted/Right Ascension" ucd="pos.eq.ra;meta.main"/>
				<column name="dec" ucd="pos.eq.dec;meta.main"/>
			</table>""",
			'spoint(radians("Right Ascension"), radians(dec))'
			"  <@ scircle(spoint(radians(10), radians(13)), radians(1))"),
		("""<table id="t" onDisk="True">
				<column name="ssa_location" type="spoint" ucd="pos.eq"/>
			</table>""",
			"ssa_location <@ scircle(spoint(radians(10), radians(13)), radians(1))"),

	]
		

class AnomalousQueryBuildingTest(testhelpers.VerboseTest):
	tdPat = """<table id="t" onDisk="True">
				<column name="raj2000" ucd="pos.eq.ra;meta.main"/>
				<column name="dej2000" ucd="pos.eq.dec;meta.main"/>
				<column name="knatter"/>
			</table>"""

	def testInjection(self):
		td = api.parseFromString(api.TableDef, self.tdPat)
		self.assertRaisesWithMsg(api.ReportableError,
			"getRadialCondition's last resort alarm triggered.",
			scs.getRadialCondition,
			(td, "); drop table users", None, None))
	
	def testOverriding(self):
		td = api.parseFromString(api.TableDef, self.tdPat)
		self.assertEqual(
			scs.getRadialCondition(td,
				"%(RA)s", "%(DEC)s", "%(SR)s",
				decColName="knatter"),
			"spoint(radians(raj2000), radians(knatter))  <@"
			" scircle(spoint(radians(%(RA)s), radians(%(DEC)s)), radians(%(SR)s))")

	def testMissingUCD(self):
		td = api.parseFromString(api.TableDef,
			self.tdPat.replace("pos.eq.dec;", ""))
		self.assertRaisesWithMsg(api.StructureError,
			"No column for pos.eq.dec;meta.main",
			scs.getRadialCondition,
			(td, "%(RA)s", "%(DEC)s", "%(SR)s"))
	

class _ConecatTable(tresc.RDDataResource):
	rdName = "data/cores"
	dataId = "import_conecat"


class ConeSearchTest(testhelpers.VerboseTest):
	resources = [("cstable", _ConecatTable()),
		("fs", tresc.fakedSimbad)]

	def testRadiusAddedSCS(self):
		svc = api.resolveCrossId("data/cores#scs")
		res = trialhelpers.runSvcWith(svc, "scs.xml",
			{"RA": ["1"], "DEC": ["2"], "SR": ["3"]}
			).getPrimaryTable()
		self.assertAlmostEqual(res.rows[0]["_r"], 0.5589304685425)
		col = res.tableDef.getColumnByName("_r")
		self.assertEqual(col.unit, "deg")

	def testRadiusAddedForm(self):
		svc = api.resolveCrossId("data/cores#scs")
		res = trialhelpers.runSvcWith(svc, "form",
			{"hscs_pos": "1, 2", "hscs_sr": 3*60}
			).getPrimaryTable()
		self.assertAlmostEqual(res.rows[0]["_r"], 0.5589304685425)

	def testRadiusAddedFormObjectres(self):
		svc = api.resolveCrossId("data/cores#scs")
		res = trialhelpers.runSvcWith(svc, "form",
			{"hscs_pos": "Aldebaran", "hscs_sr": 180*60}
			).getPrimaryTable()
		self.assertAlmostEqual(res.rows[0]["_r"], 67.9075866114036)

	def testNoRadiusWithoutPos(self):
		svc = api.resolveCrossId("data/cores#scs")
		res = trialhelpers.runSvcWith(svc, "form", {"id": "0"}
			).getPrimaryTable()
		self.assertTrue(res.rows[0]["_r"] is None)


if __name__=="__main__":
	testhelpers.main(QueryBuildingTest)
