"""
Renderers supporting upload cores.
"""

#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.


from twisted.web import template
from twisted.web.template import tags as T

from gavo import base
from gavo.svcs import weberrors
from gavo.web import formrender


class Uploader(formrender.FormRenderer):
	"""A renderer allowing for updates to individual records using file upload.

	This renderer exposes a form with a file widget.  It is likely that
	the interface will change.  And actually, you probably don't want
	to use this at all.  See :samplerd:`citigbot/q` for how Markus does
	this kind of thing today.
	"""

	name = "upload"

	@template.renderer
	def uploadInfo(self, request, tag):
		data = tag.slotData
		if data is None:
			return T.transparent()
		else:
			for key, val in data.getPrimaryTable().rows[0].items():
				tag.fillSlots(key, str(val))
			return tag

	loader = template.TagLoader(T.html[
		T.head[
			T.title["Upload"],
			T.transparent(render="commonhead"),
		],
		T.body(render="withsidebar")[
			T.h1(render="meta")["title"],
			T.p(class_="procMessage", data="result",
					render="uploadInfo")[
				template.slot(name="nAffected"),
				" record(s) modified."
			],
			T.transparent(render="form genForm")
		]
	])


class MachineUploader(Uploader):
	"""A renderer allowing for updates to individual records using file
	uploads.

	The difference to Uploader is that no form-redisplay will be done.
	All errors are reported through HTTP response codes and text strings.
	It is likely that this renderer will change and/or go away.
	"""

	name = "mupload"

	def _handleInputErrors(self, failure, request):
		request.setResponseCode(500)
		request.setHeader("content-type", "text/plain;charset=utf-8")
		request.write(failure.getErrorMessage().encode("utf-8"))
		request.finish()
		base.ui.notifyFailure(failure)
		return weberrors.Silence()

	def _notifyNonModified(self, data, request):
		request.setResponseCode(400)
		request.setHeader("content-type", "text/plain;charset=utf-8")
		request.write(("Uploading %s did not change data database.\nThis"
			" usually happens when the file already existed for an insert"
			" or did not exist for an update.\n"%(
			self.queryMeta["inputTable"].getParamDict()["File"][0],
			)).encode("utf-8"))
		request.finish()

	def _formatOutput(self, data, request):
		numAffected = data.getPrimaryTable().rows[0]["nAffected"]
		if numAffected==0:
			return self._notifyNonModified(data, request)
		request.setResponseCode(200)
		request.setHeader("content-type", "text/plain;charset=utf-8")
		request.write(("%s uploaded, %d records modified\n"%(
			self.queryMeta["inputTable"].getParamDict()["File"][0],
			numAffected)).encode("utf-8"))
		request.finish()
