#!/usr/bin/micropython

import os
import sys
import utime

import tc

maxforks = tc.cpunr

def mklog(s):
	global tm

	t = utime.time()

	fp = open('/tmp/bootlog.txt', 'at')
	fp.write("%6.1f - %s\n" % (t - tm, s))
	fp.close()

	tm = t

def debuglog(s):
	fp = open('/tmp/debugboot.log', 'at')
	fp.write("%s\n" % s)
	fp.close()

def system_command(cmd,ext):
	retries=4
	while retries > 0:
		try:
			ret=os.system(cmd)
			if ret != 0:
				if debug:
					debuglog('OS Error code %s:%d\n' % (ext, ret))
				retries -= 1
			else:
				if (retries != 4):
					if debug:
						debuglog("Successful Retry on %s\n" % ext)
				break
		except OSError:
			retries -= 1
			continue
	if (retries == 0):
		if debug:
			debuglog("\nToo many retries: %s\n", ext)


root = ''

tczout = []
tczin = []
pid = 0

showapps = 'showapps' in tc.cmdline
debug = 'debugbootload' in tc.cmdline

tm = utime.time()

for p in sys.argv[2:]:
	s = p.replace('KERNEL', tc.kernel)

	if (s in tczin) == False:
		tczin.append(s)

#Build tcz list to load, with duplicate checking
while len(tczin) > 0:
	try:
		for p in tc.readtczlist(sys.argv[1] + '/optional/' + tczin[0] + '.dep'):
			try:
				tczout.index(p)
				continue
			except ValueError:
				pass

			try:
				tczin.index(p)
				continue
			except ValueError:
				pass

			tczin.append(p)

	except OSError:
		pass

	tczout.append(tczin[0])
	del tczin[0]

#Make sure all extensions in list are really there.
for p in tczout:
   if os.access(sys.argv[1] + '/optional/' + p, os.R_OK) == False:
		tczout.remove(p)
		debuglog("Warning: %s Not Found. Extension was in onboot.lst or dependancies." % p)

mklog('Build TCZ list')
if debug:
	debuglog('Built TCZ list: %s' % (' '.join(tczout)))

# Mount extensions

if showapps:
    print()
    print("\033[1;33mMounting extensions")
    print("-------------------")
    print()

forks = 0

for p in tczout:

	pid = os.fork()

	if pid == 0:
		#This is the child process.
		if showapps:
			print(p[:-4] + ' ', end="")
			print('\033[1;33m', end="")

		os.mkdir(root + '/tmp/tcloop/' + p[:-4])
		system_command('sudo /usr/bin/mount -t squashfs -o loop ' + sys.argv[1] + '/optional/' + p + ' ' + root + '/tmp/tcloop/' + p[:-4], p[:-4])
		#Child process exits
		sys.exit(0)
	else:
		#This is the parent process
		if debug:
			debuglog("PID:%d Started for mounting %s" % (pid, p))
		forks += 1

		# Start forks up to the number of cpu cores.
		if forks >= maxforks:
			tmp=os.waitpid(0, 0)
			if debug:
				debuglog("PID:%d Finished, exit code: %d" % tmp)
			forks -= 1
		pid = 0

# There are multiple forks running, wait for them to finish.
for j in range(forks):
	tmp=os.waitpid(0, 0)
	if debug:
		debuglog("PID:%d Finished, exit code: %d" % tmp)

mklog('Mount TCZ (%d)' % (len(tczout)))
if debug:
	debuglog('Mount TCZ (%d)' % (len(tczout)))

try:
	fp = open(sys.argv[1] + '/copy2fs.flg', 'r')
	fp.close()
	copy2fsflg = True
except OSError:
	copy2fsflg = False

# Add extensions to file system

if showapps:
	print()
	print()
	print("Adding extensions to file system")
	print("--------------------------------")
	print()

forks = 0

for p in tczout:

	pid = os.fork()

	if pid == 0:
		#This is the child process
		if showapps:
			print(p[:-4] + ' ', end="")

		if copy2fsflg:
			system_command('sudo busybox cp -r ' + root + '/tmp/tcloop/' + p[:-4] + '/* /', p[:-4])
			system_command('sudo busybox.suid umount ' + root + '/tmp/tcloop/' + p[:-4], p[:-4])
			system_command('sudo busybox rm -r -f ' + root + '/tmp/tcloop/' + p[:-4], p[:-4])
		else:
			system_command('sudo busybox cp -r -f -s ' + root + '/tmp/tcloop/' + p[:-4] + '/* ' + root + '/', p[:-4])
		#The child process exits.
		sys.exit(0)
	else:
		if debug:
			debuglog("PID:%d Started for copying %s" % (pid, p))
		forks += 1
		if forks >= maxforks:
			tmp=os.waitpid(0, 0)
			if debug:
				debuglog("PID:%d Finished, exit code: %d" % tmp)
			forks -= 1
		pid = 0

# There are multiple forks running, wait for them to finish.
for j in range(forks):
	tmp=os.waitpid(0, 0)
	if debug:
		debuglog("PID:%d Finished, exit code: %d" % tmp)

mklog('Add to file system')
if debug:
	debuglog('Add to file system')

pid = os.fork()
if pid == 0:
	st = os.system('sudo /sbin/ldconfig')
	sys.exit(0)
else:
	if debug:
		debuglog("PID:%d Started for ldconfig" % pid)

pid = os.fork()
if pid == 0:
	st = os.system('sudo /sbin/depmod -b /')
	sys.exit(0)
else:
	if debug:
		debuglog("PID:%d Started for depmod" % pid)

#Wait for previous 2 forks to finish.
for i in range(2):
	tmp=os.waitpid(0, 0)
	if debug:
		debuglog("PID:%d Finished, exit code: %d" % tmp)

# Executing startup scripts

if showapps:
	print()
	print()
	print("Executing startup scripts")
	print("-------------------------")
	print('\033[0;39m')

forks = 0

# Scan for extension load scripts, and run them if found.
for p in tczout:
	script='/usr/local/tce.installed/' + p[:-4]
	pid = os.fork()

	if pid == 0:
		if showapps:
			print(p[:-4] + ' ', end="")

		if os.access( script, os.X_OK) == True:
			if debug:
				debuglog("Executing: %s" % script)
			system_command('sudo %s' % script, script)
		else:
			#if no startup script is there, create an empty file needed.
			try:
				fp = open(root + '/usr/local/tce.installed/' + p[:-4], 'wb')
				fp.close()
			except OSError:
				pass
		sys.exit(0)
	else:
		if debug:
			debuglog("PID:%d Started for %s" % (pid, p))
		forks += 1
		f = forks
		if forks >= maxforks:
			tmp=os.waitpid(0, 0)
			if debug:
				debuglog("PID:%d Finished, exit code: %d" % tmp)
			forks -= 1

for j in range(forks):
	tmp=os.waitpid(0, 0)
	if debug:
		debuglog("PID:%d Finished, exit code: %d" % tmp)

mklog('Execute startup scripts')

os.system('sudo /sbin/udevadm trigger')

mklog('udev trigger')

# ANSI COLORS
#CRE="$(echo -e '\r\033[K')"
#RED="$(echo -e '\033[1;31m')"
#GREEN="$(echo -e '\033[1;32m')"
#YELLOW="$(echo -e '\033[1;33m')"
#BLUE="$(echo -e '\033[1;34m')"
#MAGENTA="$(echo -e '\033[1;35m')"
#CYAN="$(echo -e '\033[1;36m')"
#WHITE="$(echo -e '\033[1;37m')"
#NORMAL="$(echo -e '\033[0;39m')"
