#!/usr/bin/python3
# Used to check cameras before commiting to install
# Executed before primary apt install of files

def col(id):
	"""Add color escape sequences"""
	if id == 1: return "\033[32m"
	if id == 2: return "\033[33m"
	if id == 3: return "\033[31m"
	if id == 4: return "\033[1m"
	return "\033[0m"


import subprocess
import time
import sys
import os
import re
import signal

# Backup the config file if we're upgrading
if "upgrade" in sys.argv:
	# Try to copy the config file as a backup
	try:
		subprocess.call(["cp /lib/security/howdy/config.ini /tmp/howdy_config_backup_v" + sys.argv[2] + ".ini"], shell=True)

		# Let the user know so he knows where to look on a failed install
		print("Backup of Howdy config file created in /tmp/howdy_config_backup_v" + sys.argv[2] + ".ini")
	except subprocess.CalledProcessError:
		print("Could not make an backup of old Howdy config file")

	# Don't continue setup when we're just upgrading
	sys.exit(0)

# Don't run if we're not trying to install fresh
if "install" not in sys.argv:
	sys.exit(0)

# The default picked video device id
picked = "none"


# If prompting has been disabled, skip camera check
if "HOWDY_NO_PROMPT" in os.environ:
	print(col(2) + "AUTOMATED INSTALL, YOU WILL NOT BE ASKED FOR INPUT AND CHECKS WILL BE SKIPPED" + col(0))

	# Write the default device to disk and exit
	with open("/tmp/howdy_picked_device", "w") as out_file:
		out_file.write("none;3.5")

	sys.exit(0)

fscheck = subprocess.call(["which", "streamer"], stdout=subprocess.PIPE)

if fscheck == 1:
	print(col(2) + "\nWARNING: Could not automatically find the right webcam, manual configuration after installation required\n" + col(0))
else:
	print(col(1) + "Starting IR camera check...\n" + col(0))

	# Get all devices
	devices = os.listdir("/dev/v4l/by-path")

	# Loop though all devices
	for dev in devices:
		time.sleep(.5)

		# The full path to the device is the default name
		device_name = "/dev/v4l/by-path/" + dev
		# Get the udevadm details to try to get a better name
		udevadm = subprocess.check_output(["udevadm info -r --query=all -n " + device_name], shell=True).decode("utf-8")

		# Loop though udevadm to search for a better name
		for line in udevadm.split("\n"):
			# Match it and encase it in quotes
			re_name = re.search('product.*=(.*)$', line, re.IGNORECASE)
			if re_name:
				device_name = '"' + re_name.group(1) + '"'

		# Show what device we're using
		print("Trying " + device_name)

		# Let fswebcam keep the camera open in the background
		sub = subprocess.Popen(
			["streamer -t 1:0:0 -c /dev/v4l/by-path/" + dev + " -b 16 -f rgb24 -o /dev/null 1>/dev/null 2>/dev/null"],
			shell=True,
			preexec_fn=os.setsid,
			stdout=subprocess.PIPE,
			stdin=subprocess.PIPE)

		try:
			# Ask the user if this is the right one
			print(col(2) + "One of your cameras should now be on." + col(0))
			ans = input("Did your IR emitters turn on? [y/N]: ")
		except KeyboardInterrupt:
			# Kill fswebcam if the user aborts
			os.killpg(os.getpgid(sub.pid), signal.SIGTERM)
			raise

		# The user has answered, kill fswebcam
		os.killpg(os.getpgid(sub.pid), signal.SIGTERM)

		# Set this camera as picked if the answer was yes, go to the next one if no
		if ans.lower().strip() == "y" or ans.lower().strip() == "yes":
			picked = dev
			break
		else:
			print("Interpreting as a " + col(3) + "\"NO\"\n" + col(0))

	# Abort if no camera was picked
	if picked == "none":
		print(col(3) + "No suitable IR camera found, aborting install." + col(0))
		sys.exit(23)

cert = 3.5

# Give time to read
time.sleep(.5)

print(col(1) + "\nStarting certainty auto config..." + col(0))

# Give more time to read
time.sleep(.5)

print("\n\nAfter detection, Howdy knows how certain it is that the match is correct.")
print("How certain Howdy needs to be before authenticating you can be customized.")

print(col(4) + "\nF: Fast." + col(0))
print("Allows more fuzzy matches, but speeds up the scanning process greatly.")
print(col(4) + "\nB: Balanced." + col(0))
print("Still relatively quick detection, but might not log you in when further away.")
print(col(4) + "\nS: Secure." + col(0))
print("The safest option, but will take much longer to authenticate you.")

print("\nYou can always change this setting in the config.")
prof = input("What profile would you like to use? [f/b/s]: ")

if prof.lower().strip() == "f" or prof.lower().strip() == "fast":
	cert = 4.2
elif prof.lower().strip() == "b" or prof.lower().strip() == "balanced":
	cert = 2.8
elif prof.lower().strip() == "s" or prof.lower().strip() == "secure":
	cert = 2

# Write the result to disk so postinst can have a look at it
with open("/tmp/howdy_picked_device", "w") as out_file:
	out_file.write("/dev/v4l/by-path/" + picked + ";" + str(cert))

# Add a line break
print("")
