#!/usr/bin/env python3
"""
#
# PROFIBUS - GSD file parser
#
# Copyright (c) 2016-2020 Michael Buesch <m@bues.ch>
#
# Licensed under the terms of the GNU General Public License version 2,
# or (at your option) any later version.
#
"""

from __future__ import division, absolute_import, print_function, unicode_literals

import sys
from pyprofibus.gsd.interp import GsdInterp, GsdError

import sys
import getopt


def usage():
	print("GSD file parser")
	print("")
	print("Usage: gsdparser [OPTIONS] [ACTIONS] FILE.GSD")
	print("")
	print("FILE.GSD is the GSD file to parse.")
	print("")
	print("Options:")
	print(" -o|--output FILE         Write output to FILE instead of stdout.")
	print(" -d|--debug               Enable parser debugging (default off).")
	print(" -h|--help                Show this help.")
	print("")
	print("Actions:")
	print(" -S|--summary             Print a summary of the GSD file contents.")
	print("                          (The default, if no action is specified)")
	print(" -D|--dump                Dump the GSD data structure as Python code.")
	print("")
	print("Options for --dump:")
	print(" --dump-strip             Strip leading and trailing whitespace from strings.")
	print(" --dump-notext            Do not dump PrmText.")
	print(" --dump-noextuserprmdata  Discard all ExtUserPrmData and ExtUserPrmDataRef.")
	print(" --dump-module NAME       Only dump this module. (default: Dump all)")
	print("                          Can be specified more then once to dump multiple modules.")

def out(fd, text):
	fd.write(text)
	fd.flush()

def main():
	opt_output = None
	opt_debug = False
	opt_dumpStrip = False
	opt_dumpNoText = False
	opt_dumpNoExtUserPrmData = False
	opt_dumpModules = []
	actions = []

	try:
		(opts, args) = getopt.getopt(sys.argv[1:],
			"ho:dSD",
			[ "help",
			  "output=",
			  "debug",
			  "summary",
			  "dump",
			  "dump-strip",
			  "dump-notext",
			  "dump-noextuserprmdata",
			  "dump-module=", ])
	except getopt.GetoptError as e:
		sys.stderr.write(str(e) + "\n")
		usage()
		return 1
	for (o, v) in opts:
		if o in ("-h", "--help"):
			usage()
			return 0
		if o in ("-o", "--output"):
			opt_output = v
		if o in ("-d", "--debug"):
			opt_debug = True
		if o in ("-S", "--summary"):
			actions.append( ("summary", None) )
		if o in ("-D", "--dump"):
			actions.append( ("dump", None) )
		if o in ("--dump-strip", ):
			opt_dumpStrip = True
		if o in ("--dump-notext", ):
			opt_dumpNoText = True
		if o in ("--dump-noextuserprmdata", ):
			opt_dumpNoExtUserPrmData = True
		if o in ("--dump-module", ):
			opt_dumpModules.append(v)
	if len(args) != 1:
		usage()
		return 1
	gsdFile = args[0]
	if not actions:
		actions = [ ("summary", None), ]

	try:
		if opt_output is None:
			outFd = sys.stdout
		else:
			outFd = open(opt_output, "w", encoding="UTF-8")
	except OSError as e:
		sys.stderr.write("ERROR: %s\n" % str(e))
		return 1
	try:

		interp = GsdInterp.fromFile(gsdFile, debug=opt_debug)
		for action, v in actions:
			if action == "summary":
				out(outFd, str(interp))
			elif action == "dump":
				py = interp.dumpPy(stripStr=opt_dumpStrip,
						   noText=opt_dumpNoText,
						   noExtUserPrmData=opt_dumpNoExtUserPrmData,
						   modules=(opt_dumpModules or None))
				out(outFd, py)
			else:
				assert(0)
	except GsdError as e:
		sys.stderr.write("ERROR: %s\n" % str(e))
		return 1
	except Exception as e:
		sys.stderr.write("Exception: %s\n" % str(e))
		return 1
	finally:
		if opt_output is not None:
			outFd.flush()
			outFd.close()
	return 0

if __name__ == "__main__":
	sys.exit(main())
