"""
Wrinting data in CSV.
"""

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


import codecs
import csv

from gavo import base
from gavo import rsc
from gavo.formats import common


def _defuseString(val):
	# a cheaty way of making sure we get hex escapes for non-printable stuff
	if isinstance(val, str):
		return repr(val)[1:-1]
	return val


def _defuseRow(row):
	"""returns row, where strings with non-printables have them replaced
	with backslash escapes.
	"""
	return [_defuseString(v) for v in row]


def writeDataAsCSV(table, target, acquireSamples=True,
		dialect=base.getConfig("async", "csvDialect"), headered=False):
	"""writes table to the file target in CSV.

	The CSV format chosen is controlled through the async/csvDialect
	config item.

	If headered is True, we also include table params (if present)
	in comments.
	"""
	if isinstance(table, rsc.Data):
		table = table.getPrimaryTable()
	sm = base.SerManager(table, acquireSamples=acquireSamples)

	# our targets are always binary files; csv can't deal with that.
	target = codecs.getwriter("utf-8")(target)
	writer = csv.writer(target, dialect)

	if headered:
		for param in table.iterParams():
			if param.value is not None:
				target.write(("# %s = %s // %s\r\n"%(
					param.name,
					param.getStringValue(),
					param.description)))

		writer.writerow([c["name"] for c in sm])

	for row in sm.getMappedTuples():
		writer.writerow(_defuseRow(row))
	

# NOTE: This will only serialize the primary table
common.registerDataWriter("csv_bare", writeDataAsCSV, "text/csv",
	"CSV without column labels", ".csv")
common.registerDataWriter("csv",
	lambda table, target, **kwargs:
		writeDataAsCSV(table, target, headered=True, **kwargs),
	"text/csv;header=present",
	"CSV with column labels", ".csv")
