#!/usr/bin/python3
#
# Copyright © 2019-2024 Google, Inc.
# Copyright © 2024-2025 Tomeu Vizoso
#
# SPDX-License-Identifier: MIT

import sys
import os
import argparse
import time
import datetime
from gen_parser import Parser, Reg, Enum, mask, Error


def dump_c(args, guard, func):
	p = Parser()

	try:
		p.parse(args.rnn, args.xml)
	except Error as e:
		print(e, file=sys.stderr)
		exit(1)

	print("#ifndef %s\n#define %s\n" % (guard, guard))

	print("""/* Autogenerated file, DO NOT EDIT manually!

This file was generated by the rules-ng-ng gen_header.py tool in this git repository:
http://gitlab.freedesktop.org/mesa/mesa/
git clone https://gitlab.freedesktop.org/mesa/mesa.git

The rules-ng-ng source files this header was generated from are:
""")
	maxlen = 0
	for filepath in p.xml_files:
		maxlen = max(maxlen, len(filepath))
	for filepath in p.xml_files:
		pad = " " * (maxlen - len(filepath))
		filesize = str(os.path.getsize(filepath))
		filesize = " " * (7 - len(filesize)) + filesize
		filetime = time.ctime(os.path.getmtime(filepath))
		print("- " + filepath + pad + " (" + filesize + " bytes, from " + filetime + ")")
	if p.copyright_year:
		current_year = str(datetime.date.today().year)
		print()
		print("Copyright (C) %s-%s by the following authors:" % (p.copyright_year, current_year))
		for author in p.authors:
			print("- " + author)
	if p.license:
		print(p.license)
	print("*/")

	print()
	print("#ifdef __KERNEL__")
	print("#include <linux/bug.h>")
	print("#define assert(x) BUG_ON(!(x))")
	print("#else")
	print("#include <assert.h>")
	print("#endif")
	print()

	print("#ifdef __cplusplus")
	print("#define __struct_cast(X)")
	print("#else")
	print("#define __struct_cast(X) (struct X)")
	print("#endif")
	print()

	func(p)

	print("static uint32_t rkt_get_target(uint32_t offset)")
	print("{")

	print("\tswitch(offset) {")
	for e in p.file:
		if isinstance(e, Reg):
			print("\t\tcase REG_%s:" % e.full_name)
			print("\t\t\treturn %s;" % e.domain)
	print("\t}")
	print("\treturn 0;")
	print("}")

	print("\n#endif /* %s */" % guard)


def dump_c_defines(args):
	guard = str.replace(os.path.basename(args.xml), '.', '_').upper()
	dump_c(args, guard, lambda p: p.dump())


def dump_c_pack_structs(args):
	guard = str.replace(os.path.basename(args.xml), '.', '_').upper() + '_STRUCTS'
	dump_c(args, guard, lambda p: p.dump_structs())


def dump_py_defines(args):
	p = Parser()

	try:
		p.parse(args.rnn, args.xml)
	except Error as e:
		print(e, file=sys.stderr)
		exit(1)

	file_name = os.path.splitext(os.path.basename(args.xml))[0]

	print("from enum import IntEnum")
	print("class %sRegs(IntEnum):" % file_name.upper())

	os.path.basename(args.xml)

	p.dump_regs_py()


def main():
	parser = argparse.ArgumentParser()
	parser.add_argument('--rnn', type=str, required=True)
	parser.add_argument('--xml', type=str, required=True)

	subparsers = parser.add_subparsers(required=True)

	parser_c_defines = subparsers.add_parser('c-defines')
	parser_c_defines.set_defaults(func=dump_c_defines)

	parser_c_pack_structs = subparsers.add_parser('c-pack-structs')
	parser_c_pack_structs.set_defaults(func=dump_c_pack_structs)

	parser_py_defines = subparsers.add_parser('py-defines')
	parser_py_defines.set_defaults(func=dump_py_defines)

	args = parser.parse_args()
	args.func(args)


if __name__ == '__main__':
	main()
