"""
The endplay.dealer program is a reimplementation of Hans van Staveren's dealer program
which can be used to generate hands for partnerships bidding training or for
generating statistics that can be used to design conventions, or win postmortems.

While compatibility with the original has been a design goal, the precise format of the
output is not expected to correspond 1:1 with the original program. Furthermore, several
extra options including the ability to specify actions and constraints at the command line
and some extra flags for specifying output formats are included. 
"""

import argparse
import traceback
import warnings
from endplay.dealer.runscript import run_script
import endplay.config as config

def main():
	# Parse command line
	parser = argparse.ArgumentParser(description=__doc__)
	deprecated = parser.add_argument_group(title="Deprecated options", description=
		"The following flags are listed as they were flags for the original dealer program"+\
		", but are now either ignored or cause the program to exit with an error")
	deprecated.add_argument("-e", action="store_true", help="Exhaust mode (alpha version).")
	parser.add_argument("-g", type=int, default=1000000, 
		help="Maximum number of hands to generate (default 1000000).")
	deprecated.add_argument("-l", type=int, 
		help="Instead of shuffling, deals are read from the file library.dat by M. Ginsberg")
	parser.add_argument("-m", action="store_true", help="Shows a progress meter.")
	parser.add_argument("-p", type=int, default=40, help="Maximum number of hands to produce (default 40).")
	deprecated.add_argument("-q", action="store_true", 
		help="Suppress PBN output (useful for testing, then switch it back on when generating the \"final\" sample).")
	parser.add_argument("-s", type=int, 
		help="Uses number as the seed for the random generator, running the program twice with the same seed, will produce the same sequence of hands.")
	parser.add_argument("-u", action="store_true", 
		help="Use unicode card symbols instead of the letters S, H, D, C")
	parser.add_argument("-v", action="count", default=0, 
		help="Verbose output, can be specified up to three times (-vvv). Level 1 prints statistics at the end of the run, level 2 prints any runtime generated warnings and level 3 prints full stacktraces if an exception occurs.")
	parser.add_argument("-V", action="store_true", help="Emits a version-identification string and exits")
	swapping = parser.add_mutually_exclusive_group()
	parser.set_defaults(swapping=0)
	swapping.add_argument("-0", action="store_const", dest="swapping", const=0, 
		help="No swapping, each deal is generated normally (shuffling), default.")
	swapping.add_argument("-2", action="store_const", dest="swapping", const=2,
		help="2-way swapping, after each shuffle another deal is generated by permuting E and W, leaving N and S in place (NB: not fully compatible with predeal).")
	swapping.add_argument("-3", action="store_const", dest="swapping", const=3,
		help="3-way swapping, after each shuffle another 5 deals are generated by permuting E, W, and S every which way, leaving N in place (NB: not fully compatible with predeal). not needed (NB: not compatible at all with predeal).")
	parser.add_argument("-c", action='append', default=[], 
		help="Constraint to be applied, can be specified more than once for multiple constraints")
	parser.add_argument("-f", choices=["plain", "latex", "pdf", "html"], help="Output format")
	parser.add_argument("-o", default=None, help="Name of file to save output to")
	parser.add_argument("-a", action='append', default=[], 
		help="Action to be applied, can be specified more than once")
	parser.add_argument("-b", action="store_true", help="Assign board numbers to each generated deal")
	parser.add_argument("-d", help="Cards to predeal, e.g. \"west S975,H64 east DA,C64\"")
	parser.add_argument("script", nargs='?', help="input file containing hand-descriptions and action")

	args = parser.parse_args()
	if args.V:
		exit(str(config.__version__))
	config.use_unicode = args.u
	

	# Warn/quit on deprecated flags
	if args.l:
		exit("Ginsberg library is not currently implemented")
	if args.e:
		print("Deprecated option -e ignored")
	if args.q:
		print("Deprecated option -q ignored")

	# Set up warning filter to only display warnings if verbosity >= 2
	if args.v < 2:
		warnings.simplefilter("ignore")
	else:
		warnings.showwarning = lambda msg, *args: print("Warning:", msg)

	# And away we go
	try:
		run_script(
			args.script, 
			show_progress = args.m, 
			produce = args.p, 
			generate = args.g, 
			seed = args.s, 
			verbose = args.v > 0, 
			swapping = args.swapping, 
			outformat = args.f, 
			outfile = args.o, 
			constraints = args.c, 
			actions = args.a, 
			predeal = args.d, 
			board_numbers = args.b)
	except Exception as e:
		print("dealer had to exit prematurely because of the following error:", e)
		if args.v >= 3:
			traceback.print_exc()
		exit(1)

if __name__ == "__main__":
	main()