"""
Tests for the configuration infrastructure.
"""

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


import os
import warnings
from io import StringIO

from gavo.helpers import testhelpers

from gavo import base
from gavo.base import config
from gavo.utils import fancyconfig


# The tests from fancyconfig itself
_, tests = fancyconfig._getTestSuite()
for _index, _t in enumerate(tests):
	globals()["FancyconfigTest%d"%_index] = _t


class RCParseTest(testhelpers.VerboseTest):
# NOTE: if these things actually change something in config, they
# must undo these changes (at least on success)

	def _parseFragment(self, fragment):
		config._config.addFromFp(StringIO(fragment), origin="testsuite")

	def testAuthorityRejected(self):
		self.assertRaisesWithMsg(fancyconfig.BadConfigValue,
			"[ivoa]authority must match [a-zA-Z0-9][a-zA-Z0-9._~-]{2,}$ ('more than three normal characters')",
			self._parseFragment,
			("[ivoa]\nauthority:ivo://x-invalid\n",))

	def testUnknownItemWarns(self):
		with warnings.catch_warnings(record=True) as ws:
			with testhelpers.testFile("testconfig.rc",
					"[web]\nextramad: invalid") as p:
				fancyconfig.readConfiguration(config._config, p, None)
		self.assertEqual([str(w.message) for w in ws],
			['Unknown configuration item [web] extramad ignored.'])

	def testUTF8(self):
		with testhelpers.tempConfig(("web", "sitename", "kaputt")):
			with testhelpers.testFile("testconfig.rc",
					b"[web]\nsitename: Universit\xc3\xa4t") as p:
				fancyconfig.readConfiguration(config._config, p, None)
			self.assertEqual(base.getConfig("web", "sitename"),
				'Universit\xe4t')


class UserConfigTest(testhelpers.VerboseTest):
	def testSimpleResolution(self):
		s = base.resolveCrossId("%#_test-rmk", None)
		self.assertEqual(s.maps[0].key, "foo")
	
	def testOverriding(self):
		userConfigPath = os.path.join(
			base.getConfig("configDir"), "userconfig.rd")
		base.caches.clearForName(userConfigPath[:-3])
		with open(userConfigPath, "w") as f:
			f.write("""<resource schema="__system">
				<rowmaker id="_test-rmk"><map key="bar">@bar</map>
				</rowmaker></resource>\n""")
		try:
			s = base.resolveCrossId("%#_test-rmk", None)
			self.assertEqual(s.maps[0].key, "bar")
		finally:
			os.unlink(userConfigPath)
		base.caches.clearForName(userConfigPath[:-3])

	def testNonexisting(self):
		self.assertRaisesWithMsg(base.NotFoundError,
			"Element with id 'dashiergibtsnicht' could not be located"
			" in etc/userconfig.rd",
			base.resolveCrossId,
			("%#dashiergibtsnicht", None))

	def _resetURLCaches(self):
		base.getHTTPBase.cache_clear()
		base.getHTTPSBase.cache_clear()

	def testBasesHTTP(self):
		self._resetURLCaches()
		with testhelpers.tempConfig(
				("web", "serverURL", "http://knall.org:4030/foo/bar")):
			self.assertEqual(base.getHTTPBase(),
				"http://knall.org:4030/foo/bar")
			self.assertEqual(base.getHTTPSBase(),
				"https://knall.org/foo/bar")
		self._resetURLCaches()

	def testBasesHTTPS(self):
		self._resetURLCaches()
		with testhelpers.tempConfig(
				("web", "serverURL", "https://knall.org/foo/bar")):
			self.assertEqual(base.getHTTPBase(),
				"http://knall.org/foo/bar")
			self.assertEqual(base.getHTTPSBase(),
				"https://knall.org/foo/bar")
		self._resetURLCaches()


def _modernise():
	if "test-modernise" in base.getConfig("future"):
		return "Modern"
	else:
		return "Old-Fashioned"


class FutureTest(testhelpers.VerboseTest):
	def testModern(self):
		with testhelpers.tempConfig(("general", "future", "test-modernise")):
			self.assertEqual(_modernise(), "Modern")

	def testOldFashioned(self):
		with testhelpers.tempConfig(("general", "future", "test-other")):
			self.assertEqual(_modernise(), "Old-Fashioned")

	def testNoFuture(self):
		self.assertEqual(_modernise(), "Old-Fashioned")


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