"""
A core that lets people upload RD and then goes on to publish them.

The uploads go to <resdir>/data.
"""

import os
import re

from gavo import base
from gavo import rsc
from gavo import rscdesc
from gavo.registry import publication
from gavo.svcs import core


class Core(core.Core):
	
	inputTableXML = """
		<inputTable>
		<inputKey name="inFile" tablehead="Service RD"
			description="File containing a resource descriptor for the service you want to register"
			type="file" required="True"/>
		</inputTable>"""

	outputTableXML = """
		<outputTable>
			<outputField name="npub" type="integer" required="True"
				tablehead="#Published"
				description="Number of records published from your RD."/>
		</outputTable>
		"""

	def _saveStuff(self, destDir, inputTable):
		if not os.path.exists(destDir):
			os.mkdir(destDir)
		name, file = inputTable.getParam("inFile")
		if name is None or not name.endswith(".rd"):
			raise base.ValidationError("File must exist, and its name"
				" must end with .rd.", "inFile")
		name = re.sub(r".*[/\\]", "", name)
		if not name.strip():
			raise base.ValidationError("Empty file names not allowed", "inFile")
		destName = os.path.join(destDir, name)
		with open(destName, "wb") as f:
			f.write(file.read())
		return destName

	def _publishFrom(self, srcName):
		return publication.updateServiceList(
			[rscdesc.getRD(srcName, restricted=True)],
			onlyWarn=False)

	def _cleanup(self, destDir, srcName):
		try:
			assert os.path.dirname(srcName)==destDir
			os.unlink(srcName)
		except IOError:  # don't worry about vanished files and the like.
			pass

	def run(self, service, inputTable, queryMeta):
		destDir = os.path.join(service.rd.resdir, "data")
		srcName =  self._saveStuff(destDir, inputTable)
		try:
			nPub = self._publishFrom(srcName)
		except base.ReportableError as msg:
			self._cleanup(destDir, srcName)
			raise base.ValidationError(msg, "inFile")
		except base.Error as msg:
			self._cleanup(destDir, srcName)
			raise base.ValidationError("Bad input (%s)"%str(msg), "inFile")
		base.caches.clearForName("__system__/services")
		return rsc.TableForDef(self.outputTable, rows=[
			{"npub": nPub}])
