#!/usr/bin/python

import sys
import os

from libraptz.host import host
from libraptz.config import config
from libraptz.configure import Configure
from libraptz.cdebootstrap import CDebootstrap
from libraptz.debootstrap import Debootstrap
from libraptz.multistrap import Multistrap
from libraptz.apt import Apt
from libraptz.raptzerror import RaptzException
from libraptz.image import Disk
import libraptz.comp as comp
import libraptz.progs as progs

#from libraptz.mount import Mount

# Should be moved to ui?
class Script:
	_script = []
	def add(self, cmd, *kargs):
		self._script.append((cmd, kargs))

	def run(self):
		for cmd, kargs in self._script:
			host.start(cmd.__name__)
			cmd(*kargs)
		return True

class Raptz:
	"""
Raptz rootfs handler

  raptz <command> <rootfs-path> [options]
	"""
	def chroot(self):
		""" Chroot into a rootfs """
		argp = config.get_argparser()
		argp.add_argument("-C", "--clean-mounts", help="Clean All mountpoints inside chroot at exit",
			 default=False, action='store_true')
		args = config.setup()
		if config.arg_pass:
			cmds = config.arg_pass
		else:
			cmds=["bash"]
		host.setup(args.clean_mounts)
		host.fs.mount_system()
		ret = host.runner.chroot(cmds)
		host.fs.umount_system()
		return ret

	def copy(self):
		""" Copy rootfs to new place (device for example)"""
		argp = config.get_argparser()
		argp.add_argument("-d", "--destination", default=None,
			help="Destination folder to copy rootfs too")
		args = config.setup()
		sys = comp.Tar(config.rootfs())
		sys.add(comp.UnTar(args.destination))
		sys.compress()

	def tar(self):
		""" Create one or multiple compressed tar files """
		return self._comp(comp.Tar)

	def cpio(self):
		""" Create one or multiple compressed cpio files """
		return self._comp(comp.Cpio)

	def _comp(self, basetype):
		argp = config.get_argparser()
		argp.add_argument("-r", "--raw", default=None,
			help="Create a uncompressed raw file")
		argp.add_argument("-g", "--gzip", default=None,
			help="Create a gzip compressed file")
		argp.add_argument("-b", "--bzip2", default=None,
			help="Create a bzip2 compressed file")
		argp.add_argument("-x", "--xz", default=None,
			help="Create a xz compressed file")
		args = config.setup()
		sys = basetype(config.rootfs())
		if args.raw and args.raw != "":
			sys.add(comp.Cat(args.raw))
		if args.gzip and args.gzip != "":
			sys.add(comp.GZip(args.gzip))
		if args.bzip2 and args.bzip2 != "":
			sys.add(comp.BZip2(args.bzip2))
		if args.xz and args.xz != "":
			sys.add(comp.XZ(args.xz))
		sys.compress()
		return 0


	def mkroot(self):
		""" Create a rootfs """
		argp = config.get_argparser()
		argp.add_argument("-k", "--keep", 
			help="Do not clear the rootfs directory prior to rootfs generation",
			default=False, action='store_true')
		argp.add_argument("-S", "--suite", help="Set different suite to install",
			default=None)
		argp.add_argument("-b", "--bootstrap", default="multistrap",
			help="bootstrap mode (multstrap*, debootstrap, cdebootstrap)"
		)
		args = config.setup()
		host.setup()
		sc = Script()
		if args.bootstrap == "multistrap":
			bsp = Multistrap()
		elif args.bootstrap == "debootstrap":
			bsp = Debootstrap()
		elif args.bootstrap == "cdebootstrap":
			bsp = CDebootstrap()
		else:
			raise "Unknown mode " + args.bootstrap
		apt = Apt()
		cfg = Configure()
		if not args.keep:
			cfg.clean()
		sc.add(bsp.bootstrap)
		sc.add(cfg.setup)
		sc.add(bsp.secondstage)
		sc.add(bsp.finalize)
		if not bsp.fullinstall():
			sc.add(apt.update)
			sc.add(apt.install, config.keyrings())
			sc.add(apt.update)
			sc.add(apt.install, config.packages())
		sc.add(cfg.configure)
		sc.run()
		host.fs.umount_system()
		return 0

	def image(self):
		""" Create an system image from a rootfs """
		argp = config.get_argparser()
		argp.add_argument("-i", "--image", default=config.rootfs()+".img",
			help="bootstrap mode (default is <rootfs-path>.img)"
		)
		args = config.setup()
		i = Disk(config.rootfs(), config.get_conf_path("disk.cfg") , args.image)
		print "Generating %s from %s using %s" % (args.image, config.rootfs(), config.get_conf_path("disk.cfg"))
		if i.gen_img():
			print "Done"
		else:
			print "Fail"
		return 0

	def help(self):
		""" Print this help"""
		print self.__doc__
		print "Commands:"
		for m in dir(self):
			if m.startswith("_"):
				continue
			print "  %-10s - %s" %(m, getattr(self, m).__doc__)
		print ""

ret = 0
raptz = Raptz()
func = getattr(raptz, config.arg_command)
progs.lock()
try:
	ret = func()
	config.save()
except RaptzException as e:
	if config.debug:
		raise
	else:
		print
		print "ERROR: " + str(e)
		print
	exit(1)

try:
	os.wait()
except OSError as e:
	if e.errno == 10: # No child process
		pass
	else:
		raise
exit(ret)
