"""
BulkSMS/CLI.py: Command-line wrapper around BulkSMS.
Author: David M. Wilson <dw-BulkSMS_CLI.py@botanicus.net>.
"""

import getopt, os, time
import BulkSMS, BulkSMS.PhoneBook



def usage(argv0):
	"""
	Print command-line program usage.
	"""

	print __doc__
	print "%s send    <opts> <msg> <phone1> [phone2 ..]" % argv0
	print "%s quote   <opts> <msg> <phone1> [phone2 ..]" % argv0
	print "%s report  <opts> <msg_id> [phone1]" % argv0
	print "%s credits <opts>" % argv0
	print
	print "Options:"
	print "   --sender=<sender>        Sender field."
	print "   --flash                  Send as flash message."
	print "   --dca=<7bit|8bit|16bit>  Data coding alphabet."
	print "   --report                 Request delivery report."
	print "   --cost_route=<1|2|3>     Message route."
	print "   --nodup                  Suppress duplicate messages."
	print "   --wait=<integer>         Seconds to wait between failures."
	print "   --retry=<integer>        Number of attempts before failing."
	print "   --username=<string>      Username to connect using."
	print "   --password=<string>      Password to connect using."
	print "   --poll                   Display message status until delivered."
	print
	print "   send  sends a message,"
	print "  quote  retrieves the cost for sending a message,"
	print " report  retrieves a delivery report, and"
	print "credits  retrieves the total credits on your account."
	print
	print "A simple '<keyword>: <phone1>, <phone2>, <phone3><nl>' format"
	print "shortcut database is stored in your homedir/.sms_phonebook."
	print



def format_status_report(triple):
	"""
	Return a string containing a formatted version of the given <triple>. The
	<triple> is one returned in the list from BulkSMS.get_report().
	"""

	return "%-14s %2s %s" % triple




def poll_report(server, msg_id):
	"""
	Poll <server> every 10 seconds for up to 5 minutes, dumping a message to
	stdout every time the state of <msg_id> changes. Once all recipients have
	received a message, return.
	"""

	poll_time = 10
	poll_left = 5 * 60
	last_result = None
	result = None

	print

	while poll_left:
		last_result = result
		result = server.get_report(msg_id)

		if last_result != result:
			for triple in result:
				print format_status_report(triple)

		all_done = True

		for item in result:
			if item[1] != 11:
				all_done = False

		if all_done:
			return

		poll_left -= poll_time
		time.sleep(poll_time)






def command_line(argv):
	"""
	Act as a command-line tool.
	"""

	long_options = [
		'sender=', 'flash', 'dca=', 'report', 'cost_route=', 'nodup',
		'wait=', 'retry=', 'username=', 'password=', 'poll'
	]


	if len(argv) < 2:
		usage(argv[0])
		return 1

	try:
		options, arguments = getopt.gnu_getopt(argv[1:], "", long_options)
	except:
		usage(argv[0])
		return 1


	if len(arguments) > 0:
		mode = arguments[0]
		arguments.pop(0)

	else:
		mode = None


	command_arguments = {}
	poll = False

	command_arguments['sender'] = os.getenv('BULKSMS_SENDER')

	username = os.getenv('BULKSMS_USERNAME')
	password = os.getenv('BULKSMS_PASSWORD')


	if 'BULKSMS_REPORT' in os.environ:
		command_arguments['want_report'] = 1



	for option, argument in options:
		if option == "--sender":
			command_arguments['sender'] = argument

		elif option == "--flash":
			command_arguments['msg_class'] = 0

		elif option == "--dca":
			command_arguments['dca'] = argument

		elif option == "--report":
			command_arguments['want_report'] = 1

		elif option == "--cost_route":
			command_arguments['cost_route'] = argument

		elif option == "--nodup":
			command_arguments['nodup'] = 1

		elif option == "--wait":
			command_arguments['transient_wait'] = argument

		elif option == "--retry":
			command_arguments['transient_retries'] = argument

		elif option == "--username":
			username = argument

		elif option == "--password":
			password = argument

		elif option == "--mode":
			mode = argument

		elif option == "--poll":
			command_arguments['want_report'] = 1
			poll = True


	if mode not in ( "send", "quote", "credits", "report" ):
		print "!!! Please specify a valid mode."
		return 1

	if not username or not password:
		print "!!! Please specify a username and password."
		return 1



	server = BulkSMS.BulkSMS(username, password)
	server.phonebook = BulkSMS.PhoneBook.HomedirPhoneBook()

	if mode == 'send' or mode == 'quote':
		message = arguments.pop(0)
		recipients = arguments

		if len(recipients) < 1:
			print "!!! Please specify your message and at least one recipient."
			return 1

		if mode == 'quote':
			cost = server.quote_sms(recipients, message, **command_arguments)
			print "Message cost:", BulkSMS.format_credits(cost), "credits."

		else:
			msg_id = server.send_sms(recipients, message, **command_arguments)
			print "Message sent. Message ID:", msg_id

			if poll:
				poll_report(server, msg_id)

		return 0


	if mode == 'credits':
		print "Credits available:", BulkSMS.format_credits(server.get_credits())
		return 0


	if mode == 'report':
		if len(arguments) < 1 or len(arguments) > 2:
			print "!!! Please specify a <msg_id> and optionally a recipient."
			return 0

		msg_id = arguments.pop(0)
		
		if len(arguments):
			recipient = arguments.pop(0)

		else:
			recipient = None


		report = server.get_report(msg_id, recipient)

		for triple in report:
			print format_status_report(triple)

		print
