#!/usr/bin/python3
import os
import readline
import shlex
import sys
import subprocess
import socket

tuerSock = "/run/tuer.sock"

# use a histfile
histfile = os.path.join(os.path.expanduser("~"), ".tyshellhist")
try:
    readline.read_history_file(histfile)
except IOError:
    pass
import atexit
atexit.register(readline.write_history_file, histfile)
atexit.register(print, "Bye")

# available commands
def helpcmd(c):
	print("Available commands: %s" % ", ".join(sorted(longcommands.keys())))

def extcmd(cmd):
	def run(c):
		ret = subprocess.call(cmd)
		if ret != 0:
			print("Command returned non-zero exit statis %d" % ret)
	return run

def sendcmd(addr, cmd):
	def run(c):
		print("Running %s..." % (cmd))
		s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
		s.connect(addr)
		s.send(cmd.encode())
		data = s.recv(4)
		s.close()
		print("...done")
		if data != b'1':
			print("Received unexpected answer %s" % str(data))
	return run

def exitcmd(c):
	sys.exit(0)

commands = {
	'exit': exitcmd,
	'help': helpcmd,
	'open': sendcmd(tuerSock, 'open'),
	'close': sendcmd(tuerSock, 'close'),
	'buzz': sendcmd(tuerSock, 'buzz'),
}

# command convenience shortcuts
def filterCommonPrefix (strings, length):
	# ignores duplicates in the string list "strings"
	toremove=[]
	for a in strings:
		for b in strings:
			if a != b:
				if a[:length] == b[:length]:
					toremove.append(a)
					toremove.append(b)
	ret = list(strings) # copy
	for x in toremove:
		try:
			ret.remove(x)
		except ValueError:
			pass
	return ret

def shortcutify (dic):
	maxlen = 0
	for x in dic.keys():
		if len(x) > maxlen:
			maxlen = len(x)
	for i in range(maxlen):
		shortable = filterCommonPrefix (dic.keys(), i)
		for x in shortable:
			dic[x[:i]] = dic[x]
	return dic # only for convenience, as dic is passed by reference

longcommands = commands.copy()
shortcutify (commands)


# input loop
print("Welcome to tyshell. Use help to see what you can do.")
while True:
	try:
		command = input("$ ")
	except EOFError:
		print()
		break
	command = shlex.split(command)
	if not len(command): continue
	# execute command
	if command[0] in commands:
		try:
			commands[command[0]](command)
		except Exception as e:
			print("Error while executing %s: %s" % (command[0], str(e)))
	else:
		print("Command %s not found. Use help." % command[0])