#! /usr/bin/ python
# -*- coding=utf-8 -*-

from cStringIO import StringIO
import contextlib
import os
import random
import urlparse

import astropy
from astropy.vo.samp import SAMPIntegratedClient
from astropy.table import Table
import pyvo


HSOY_SCS_URL = 'http://dc.zah.uni-heidelberg.de/hsoy/q/q/scs.xml?'
GAIA_TAP_URL = 'http://dc.zah.uni-heidelberg.de/tap'

GAIA_CROSS_QUERY = """
SELECT TOP 1000000 ul.*, gaia.source_id, gaia.raj2000,
		gaia.dej2000,
		(ul.raj2000+(15*ul.pmRA/COS(radians(ul.dej2000)))) AS comp_raj2015,
		(ul.dej2000+(15*ul.pmDE)) AS comp_dej2015,
		(gaia.raj2000-(ul.raj2000+(15*ul.pmRA/COS(radians(ul.dej2000)))))*cos(radians(ul.dej2000)) AS diffg_ra,
		(gaia.dej2000-(ul.dej2000+(15*ul.pmDE))) AS diffg_dec,
		gaia.ra_error, gaia.dec_error, gaia.pmra, gaia.pmdec,
		gaia.pmra_error, gaia.pmdec_error, gaia.parallax,
		gaia.parallax_error, gaia.phot_g_mean_mag, gaia.phot_g_mean_flux,
		gaia.phot_g_mean_flux_error, gaia.ref_epoch
FROM gaia.dr1 AS gaia
JOIN tap_upload.t1 AS ul
	ON 1=CONTAINS (
		POINT('', gaia.raj2000, gaia.dej2000),
		CIRCLE('',
		(ul.raj2000+(15*ul.pmRA/COS(radians(ul.dej2000)))),
		(ul.dej2000+(15*ul.pmDE)),
		0.5/3600))"""


class EmptyCone(Exception):
	"""is raised when no hsoy objects are found in the cone passed.
	"""

def get_hsoy_stats(ra, dec, sr):
	res = pyvo.conesearch(HSOY_SCS_URL, pos=[ra, dec], radius=sr)
	cone_table = res.votable.to_table()
	if len(cone_table)==0:
		raise EmptyCone()

	tap_service = pyvo.dal.TAPService(GAIA_TAP_URL)

	res = tap_service.run_async(GAIA_CROSS_QUERY,
		uploads = {'t1': ('inline', cone_table)})

	matched_table = res.votable.to_table()
		
	n = len(matched_table)
	return (n,
		sum(abs(matched_table["diffg_ra"]))/n*3.6e6,
		sum(abs(matched_table["diffg_dec"]))/n*3.6e6,
		sum(matched_table["diffg_ra"])/n*3.6e6,
		sum(matched_table["diffg_dec"])/n*3.6e6)


def make_vo_table(tuples, names):
	return Table(
		[[t[col_ind] for t in tuples] for col_ind in range(len(tuples[0]))],
		names=names)


@contextlib.contextmanager
def samp_accessible(astropy_table):
	"""a context manager making astroy_table available under a (file)
	URL for the controlled section.

	This is useful with uploads.
	"""
	handle, f_name = tempfile.mkstemp(suffix=".xml")
	with os.fdopen(handle, "w") as f:
		astropy_table.write(output=f,
			format="votable")
	try:
		yield "file://"+f_name
	finally:
		os.unlink(f_name)


@contextlib.contextmanager
def SAMP_conn():
	"""a context manager to give the controlled block a SAMP connection.

	The program will disconnect as the controlled block is exited.
	"""
	client = SAMPIntegratedClient(name="smpsmp",
		description="A sample for the use of SAMP")
	client.connect()
	try:
		yield client
	finally:
		client.disconnect()


def main():
	results = []
	for i in range(200):
		ra, dec = random.random()*360.0, random.random()*180-90,
		try:
			stats = get_hsoy_stats(ra, dec, 0.1)
		except EmptyCone:
			continue
		results.append((ra, dec)+stats)

	global_stats = make_vo_table(results,
		["ra",  "dec", "n", "meanabsdra", "meanabsddec",
		"meandra", "meandec"])

	with open("stats.vot", "w") as f:
		global_stats.write(output=f, format="votable")


if __name__=="__main__":
	main()
