#!/usr/bin/env python3

# (c) Copyright 1996-2012 ECMWF.
# 
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
# In applying this licence, ECMWF does not waive the privileges and immunities 
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.

# Documentation is available on Confluence
# https://confluence.ecmwf.int/display/METK/MetKit+configuration


import mysql.connector
import yaml
import re
import os

connectionDetails = dict(
	host = "webapps-db-prod",
	user = os.environ['PARAM_DB_USER'],
	passwd = os.environ['PARAM_DB_PASSWORD'])

def execute(database, fun, prefix=None, asList=False, lowercase=True):
	connection = mysql.connector.connect(**connectionDetails)
	cursor = connection.cursor()
	cursor.execute("USE " + database)
	r = fun(cursor, prefix, asList, lowercase) if (prefix) else fun(cursor)
	cursor.close()
	connection.close()
	return r

################################################################################################

def ids(cursor, prefix, asList, lowercase):

	PRODGEN = {}
	if os.path.exists("prodgen-" + prefix + "ids.yaml"):
		with open("prodgen-" + prefix + "ids.yaml") as f:
			PRODGEN = yaml.load(f.read(), Loader=yaml.FullLoader)

	IDS = {}
	if os.path.exists(prefix + "ids.yaml"):
		with open(prefix + "ids.yaml") as f:
			IDS = yaml.load(f.read(), Loader=yaml.FullLoader)
			if asList:
				# Convert list of lists to dictionary
				IDS = {item[0]: item[1:] for item in IDS}

	cursor.execute("select * from " + prefix)

	for data in cursor.fetchall():
		paramid, abbr, longname = int(data[0]), data[1], data[2]
		if lowercase:
			abbr = abbr.lower()

		abbr = re.sub(r"\W", "_", abbr)
		abbr = re.sub(r"_+", "_", abbr)
		abbr = re.sub(r"^_", "", abbr)
		abbr = re.sub(r"_$", "", abbr)

		if not abbr:
			abbr = "_%s_%06d" % (prefix, paramid,)

		entry = [abbr.strip(), longname.strip()]

		if paramid in PRODGEN:
			pgen = [str(x).lower() for x in PRODGEN[paramid]]
			p = []
			for n in pgen:
				if (
					n not in entry
				):  #  and (' ' not in n) and ('.' not in n): #  and ('-' not in n):
					entry.append(n)
					p.append(n)

		entry = tuple(entry)

		if entry[0].lower() == entry[1].lower():
			entry = tuple([entry[0]])
		else:
			entry = tuple(entry)

		if paramid in IDS:
			before = tuple(IDS[paramid])
			if before != entry:
				print(
					"WARNING! updated {}id: {},  {} => {}".format(prefix,  paramid, before, entry)
				)
				IDS[paramid] = list(entry)
		else:
			print("new {}id: {} {}".format(prefix, paramid, entry))
			IDS[paramid] = list(entry)

	for paramid, entry in PRODGEN.items():
		if paramid not in IDS:
			print("WARNING! adding pseudo-{}id: {},  {}".format(prefix, paramid, tuple(entry)))
			IDS[paramid] = entry

	if asList:
		# Sort by key and convert to list of lists
		return [[k] + v for k, v in sorted(IDS.items(), key=lambda item: item[0])]
	return IDS


################################################################################################

def getListOfRT(cursor, group_id):
	def sorted(cursor):
		cursor.execute("SELECT code FROM odbadmin_reporttype WHERE group_id = " + str(group_id))
		r = [r[0] for r in cursor.fetchall()]
		r.sort()
		return r
	return sorted(cursor)

T = """- context:\n    type: [ofb,mfb,oai,sfb,fsoifb,fcdfb,ofa]\n    obsgroup: [%(OBSGROUP)s]\n  defaults:\n    reportype: [%(REPORTYPE_LIST)s]\n"""

def reportype(cursor):
	cursor.execute("SELECT id,marsname FROM odbadmin_group")
	GROUP = dict([(r[0],str(r[1]).lower()) for r in cursor.fetchall()])

	cursor.execute("SELECT DISTINCT group_id FROM odbadmin_reporttype ORDER BY group_id")
	groups = [r[0] for r in cursor.fetchall()]
	def expand(g):
		return T % dict(OBSGROUP = GROUP[g], REPORTYPE_LIST = "/".join([str(r) for r in getListOfRT(cursor, g)]))
	return "\n".join([expand(group_id) for group_id in groups])

################################################################################################

def header(f,o):
	f.write(
		"---\n# File automatically generated by %s --%s\n# Do not edit\n\n"
		% (os.path.basename(__file__), o)
	)

options = 'chem param reportype'.split()

def main():
	import sys
	opts = sys.argv[1:]
	if len(opts) != 1 or opts[0].lstrip('-') not in options:
		print(sys.argv[0] + ": Possible options: --" + ", --".join(options))
		sys.exit(1)
	o = opts[0].lstrip('-')
	match o:
		case 'chem':
			content = execute("param", ids, o, True, False)
			with open(o + "ids.yaml", "w") as f:
				header(f, o)
				yaml.safe_dump(content, f, default_flow_style=None)
		case 'param':
			content = execute("param", ids, o)
			with open(o + "ids.yaml", "w") as f:
				header(f, o)
				yaml.safe_dump(content, f, default_flow_style=False)
		case 'reportype':
			with open("reportype.yaml", "w") as f:
				header(f, o)
				f.write(execute("odbgov", reportype))

if __name__ == "__main__":
	main()
