#!/usr/bin/python -ttu
# vim: ai ts=4 sts=4 et sw=4

#    Copyright (c) 2007 Intel Corporation
#
#    This program is free software; you can redistribute it and/or modify it
#    under the terms of the GNU General Public License as published by the Free
#    Software Foundation; version 2 of the License
#
#    This program is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
#    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
#    for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc., 59
#    Temple Place - Suite 330, Boston, MA 02111-1307, USA.


import gettext
import gtk.glade
import locale
import os
import platform
import string
import sys
import re
import traceback

from optparse import OptionParser

sys.path.insert(0, '/usr/share/pdk/lib')
import SDK
import mic_cfg
import pdk_utils

_ = gettext.lgettext

ENVIRONMENT_VARS = {
    'PATH' : '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
    'PERL_BADLANG' : '0',
}

debug = False
if mic_cfg.config.has_option('general', 'debug'):
    debug = int(mic_cfg.config.get('general', 'debug'))

# We will only load the GUI library code if we have no arguments specified
if len(sys.argv) == 1:
    try:
        import gui
    except RuntimeError:
        traceback.print_exc()
        # Probably running in a text console
        pass

sdk = SDK.SDK()

def main():
    if sys.hexversion < 0x2040000:
        print >> sys.stderr, _("Error: %s depends on a Python version of at least 2.4!") % (sys.argv[0])
        sys.exit(1)
    # Make sure the executables we need are on the system
    verifyExes()
    # Set needed environment variables
    setEnvironmentVariables()
    # Initial stuff for Internationlization and Localization support.
    # Locale stuff
    # internationalization
    locale.setlocale(locale.LC_ALL)

    # More info: http://docs.python.org/lib/i18n.html
    for module in gtk.glade, gettext:
        module.bindtextdomain('moblin-image-creator')
        module.textdomain('moblin-image-creator')

    if len(sys.argv) == 1:
        if not pdk_utils.areWeRoot():
            print _("Error: Must run image creator with sudo or run as root")
            print _("Example, run image creator:  sudo image-creator")
            sys.exit(1)
        if os.getenv("DISPLAY"):
            try:
                gui.App().run()
                return 0
            except:
                traceback.print_exc()
                print _("Error: Unable to run the GUI, maybe you are in a text console")
                print _("Do -h for help")
                return 1
        else:
            print
            print _("Error: Your DISPLAY environment variable is NOT set")
            print _("The Moblin Image Creator GUI can NOT run")
            return 1

    options, args = parseCommandLine()
    if options.cmd == "version":
        display_version()
    elif options.cmd == "list-platforms":
        list_platforms()
    elif options.cmd == "clear-rootstraps":
        clear_rootstraps()
    elif options.cmd == "list-projects":
        list_projects()
    elif options.cmd == "list-targets":
        list_targets(options)
    elif options.cmd == "list-fsets":
        list_fsets(options)
    elif options.cmd == "list-pkgs":
        list_pkgs(options)
    elif options.cmd == "list-sources-files":
        list_sources_files(options)
    elif options.cmd == "create-project":
        create_project(options)
    elif options.cmd == "delete-project":
        delete_project(options)
    elif options.cmd == "umount-project":
        umount_project(options)
    elif options.cmd == "umount-target":
        umount_target(options)
    elif options.cmd == "run-target":
        run_target(options)
    elif options.cmd == "run-project":
        run_project(options)
    elif options.cmd == "create-target":
        create_target(options)
    elif options.cmd == "delete-target":
        delete_target(options)
    elif options.cmd == "install-fset":
        install_fset(options)
    elif options.cmd == "add-repo":
        add_repo(options)
    elif options.cmd == "update-project":
        update_project(options)
    elif options.cmd == "update-target":
        update_target(options)
    elif options.cmd in ["create-live-usb", "create-live-usbrw", "create-nfslive-usb", "create-install-usb", "create-live-iso", "create-nfslive-iso", "create-install-iso", "create-nand"]:
        create_image(options)
    elif options.cmd == "chroot-project":
        chroot_project(options)
    elif options.cmd == "chroot-target":
        chroot_target(options)
    elif options.cmd == "save-project":
        save_project(options)
    elif options.cmd == "load-project":
        load_project(options)
    else:
        print _("Unknown command specified")
        return 1
    sdk.umount()
    return 0

def parseCommandLine():
    valid_commands = {
        # command name,         requires root priviledge
        "chroot-project" :      1,
        "chroot-target" :       1,
        "clear-rootstraps" :    1,
        "create-install-usb" :  1,
        "create-live-usb" :     1,
        "create-live-usbrw" :   1,
        "create-nfslive-usb" :  1,
        "create-live-iso" :     1,
        "create-nfslive-iso" :  1,
        "create-install-iso" :  1,
        "create-nand" :         1,
        "create-project" :      1,
        "create-target" :       1,
        "delete-project" :      1,
        "delete-target" :       1,
        "install-fset" :        1,
        "add-repo" :            1,
        "list-fsets" :          0,
        "list-pkgs" :           0,
        "list-sources-files" :  0,
        "list-platforms" :      0,
        "list-projects" :       0,
        "list-targets" :        0,
        "load-project" :        1,
        "run-project" :         1,
        "run-target" :          1,
        "save-project" :        1,
        "umount-project" :      1,
        "umount-target" :       1,
        "update-project" :      1,
        "update-target" :       1,
        "version" :             0,
    }
    valid_command_string = ""
    commands = valid_commands.keys()
    commands.sort()
    # Get all but the last one
    for command in commands[:-1]:
        valid_command_string += "%s, " %  command
    valid_command_string += "or %s" % commands[-1]

    parser = OptionParser(add_help_option=False)

    parser.add_option("--version", help=_("Display version"),
        dest = "version", action="store_true", default=False)
    parser.add_option("-c", "--command", dest="cmd",
        help=_("Where CMD is one of: %s") % valid_command_string, metavar="CMD")
    parser.add_option("--platform-name", dest="platform_name",
        help=_("Platform name"))
    parser.add_option("--project-name", dest="project_name",
        help=_("Project name"))
    parser.add_option("--project-description", dest="project_desc",
        help=_("Project description"))
    parser.add_option("--project-path", dest="project_path",
        help=_("Project path"))
    parser.add_option("-t", "--target-name", dest="target_name",
        help=_("Target name"))
    parser.add_option("--fset-name", dest="fset_names", action="append",
        help=_("Feature set identifier"))
    parser.add_option("--repo-name", dest="repo_name",
        help=_("Repo name"))
    parser.add_option("--repo-url", dest="repo_url", 
        help=_("Repo URL"))
    parser.add_option("--image-name", dest="image_name",
        help=_("Name to use for target image file"))
    parser.add_option("--run-command", dest="run_command",
        help=_("Command to execute inside a project or target chroot filesystem"))
    parser.add_option("--bypass-rootstrap",
        action="store_false", dest="use_rootstrap", default=True,
        help=_("Disable creation or use of rootstrap files"))
    parser.add_option("-d", "--enable-debug",
        action="store_true", dest="debug", default=False,
        help=_("Enable additional debug package while installing fsets"))
    parser.add_option("-f", "--file-name", dest="file_name",
        help=_("Filename to use when saving or restoring a project, if .mic.tar.bz2 is not the extension during a save then .mic.tar.bz2 will be appended"))
    parser.add_option("-h", "--help", help=_("show this help message and exit"),
        dest = "help", action="store_true", default=False)
    examples = """
Examples:
<Adding a new project>
    image-creator --command=create-project \\
                  --platform-name='donley' \\
                  --project-name='MyProject' \\
                  --project-desc='Example project' \\
                  --project-path=/usr/src/projects/myproject

<Delete a project>
    image-creator --command=delete-project \\
                  --project-name='MyOtherProject'

<Unmount a project> Normally this will not be needed as projects are
                    automatically unmounted upon exit.
    image-creator --command=umount-project \\
                  --project-name='MyOtherProject'

<Unmount a target>  Normally this will not be needed as targets are
                    automatically unmounted upon exit
    image-creator --command=umount-target \\
                  --project-name='MyOtherProject' \\
                  --target-name='MyTarget'

<Run a command inside a project>
    image-creator --command=run-project \\
                  --project-name='MyOtherProject' \\
                  --run-command='dpkg -l'

<Run a command inside a target>
    image-creator --command=run-target \\
                  --project-name='MyOtherProject' \\
                  --target-name='MyTarget' \\
                  --run-command='dpkg -l'

<Adding a new target to an existing project>
    image-creator --command=create-target \\
                  --project-name='MyProject' \\
                  --target-name='MyTarget'

<Delete a target>
    image-creator --command=delete-target \\
                  --project-name='MyProject' \\
                  --target-name='MyOtherTarget'

<Installing a Function Set (fset) into a given target>
    image-creator --command=install-fset \\
                  --platform-name='donley' \\
                  --project-name='MyProject' \\
                  --target-name='MyTarget' \\
                  --fset='Core' \\

<Change into a given project buildroot filesystem>
    image-creator --command=chroot-project \\
                  --project-name='MyProject' \\

<Change into a given projects target filesystem>
    image-creator --command=chroot-target \\
                  --project-name='MyProject' \\
                  --target-name='MyTarget' \\

<Updating a given target inside a project>
    image-creator --command=update-target \\
                  --project-name='MyProject' \\
                  --target-name='MyTarget' \\

<Updating a given project>
    image-creator --command=update-project \\
                  --project-name='MyProject'

<Create a image>
    image-creator --command= [ create-live-usb | \\
                               create-live-usbrw | \\
                               create-nfslive-usb | \\
                               create-install-usb |  \\
                               create-live-iso | \\
                               create-nfslive-iso | \\
                               create-install-iso | \\
                               create-nand ] \\
                  --project-name='MyProject' \\
                  --target-name='MyTarget' \\
                  --image-name='MyImage'

<Save a project>
    image-creator --command=save-project \\
        --project-name='MyProject' \\
        --file-name='file_name_to_save_project'

<Load a saved project>
    image-creator --command=load-project \\
        --project-name='MyProject' \\
        --file-name='file_name_of_saved_project'
        --project-path='path_to_restore_project_to'
                  """

    (options, args) = parser.parse_args()
    # if nothing at all is passed in then return back
    if not options and not args:
        return options, args
    if options.help:
        parser.print_help()
        print
        print examples
        sys.exit(0)
    if options.version:
        display_version()
        sys.exit(0)
    # now lets validate stuff
    if not options.cmd:
        parser.error(_("Must specify a -c/--command argument"))
    if options.cmd not in valid_commands:
        parser.error(_("Command specified for option -c/--command invalid.  Valid commands are: %s") % valid_command_string)
    need_root = valid_commands[options.cmd]
    if need_root and not pdk_utils.areWeRoot():
        parser.error(_("Command specified requires you to run as root or using sudo.  Command is: %s") % options.cmd)
    # Our FSets are converted to lowecase, so do the same for the command line
    # argument
    if options.fset_names:
       options.fset_names = [f.lower() for f in options.fset_names]
    if options.cmd == "list-targets" and not options.project_name:
        parser.error(_("Must specify a project-name when using %s command.") % options.cmd)
    if options.cmd == "list-fsets" and not options.platform_name:
        parser.error(_("Must specify platform-name when using %s command") % options.cmd)
    if options.cmd == "list-pkgs":
        if not options.platform_name:
            parser.error(_("Must specify platform-name when using %s command") % options.cmd)
        if not options.fset_names:
            parser.error(_("Must specify at least one fset when using %s command") % options.cmd)
    if options.cmd == "list-sources-files":
        if not options.platform_name:
            parser.error(_("Must specify platform-name when using %s command") % options.cmd)
    if options.cmd == "create-project":
        if not options.platform_name:
            parser.error(_("Must specify platform-name when using %s command") % options.cmd)
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.project_desc:
            parser.error(_("Must specify project-description when using %s command") % options.cmd)
        if not options.project_path:
            parser.error(_("Must specify project-path when using %s command") % options.cmd)
    if options.cmd == "delete-project" and not options.project_name:
        parser.error(_("Must specify project-name when using %s command") % options.cmd)
    if options.cmd == "umount-project" and not options.project_name:
        parser.error(_("Must specify project-name when using %s command") % options.cmd)
    if options.cmd == "umount-target":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.target_name:
            parser.error(_("Must specify target-name when using %s command") % options.cmd)
    if options.cmd == "run-project":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.run_command:
            parser.error(_("Must specify run-command when using %s command") % options.cmd)
    if options.cmd == "run-target":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.target_name:
            parser.error(_("Must specify target-name when using %s command") % options.cmd)
        if not options.run_command:
            parser.error(_("Must specify run-command when using %s command") % options.cmd)
    if options.cmd == "update-project" and not options.project_name:
        parser.error(_("Must specify project-name when using %s command") % options.cmd)
    if options.cmd == "create-target" or options.cmd == "delete-target" or options.cmd == "update-target":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.target_name:
            parser.error(_("Must specify target-name when using %s command") % options.cmd)
    if options.cmd == "install-fset":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.target_name:
            parser.error(_("Must specify target-name when using %s command") % options.cmd)
        if not options.fset_names:
            parser.error(_("Must specify at least one fset-name when using %s command") % options.cmd)
    if options.cmd == "add-repo":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.target_name:
            parser.error(_("Must specify target-name when using %s command") % options.cmd)
        if not options.repo_name:
            parser.error(_("Must specify repo-name when using %s command") % options.cmd)        
        if not options.repo_url:
            parser.error(_("Must specify repo-url when using %s command") % options.cmd)                
    if options.cmd == "create-live-usb" or options.cmd == "create-live-usbrw" or options.cmd == "create-nfslive-usb" or options.cmd == "create-install-usb" or options.cmd == "create-live-iso" or options.cmd == "create-nfslive-iso" or options.cmd == "create-install-iso":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.target_name:
            parser.error(_("Must specify target-name when using %s command") % options.cmd)
        if not options.image_name:
            parser.error(_("Must specify image-name when using %s command") % options.cmd)
    if options.cmd == "chroot-project":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
    if options.cmd == "chroot-target":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.target_name:
            parser.error(_("Must specify target-name when using %s command") % options.cmd)
    if options.cmd == "save-project" or options.cmd == "load-project":
        if not options.project_name:
            parser.error(_("Must specify project-name when using %s command") % options.cmd)
        if not options.file_name:
            parser.error(_("Must specify file-name when using %s command") % options.cmd)
    if options.cmd == "load-project":
        if not options.project_path:
            parser.error(_("Must specify project-path when using %s command") % options.cmd)
        if not options.file_name.endswith(".mic.tar.bz2"):
            parser.error(_("Filename must have the extension: .mic.tar.bz2"))
    if options.project_path:
        options.project_path = os.path.realpath(os.path.abspath(os.path.expanduser(options.project_path)))
    if options.file_name:
        options.file_name = os.path.realpath(os.path.abspath(os.path.expanduser(options.file_name)))

    return options, args

def clear_rootstraps():
    sdk.clear_rootstraps()
    
def display_version():
    print _("Moblin Image Creator %s") % sdk.version

def list_platforms():
    for key in sorted(sdk.platforms.iterkeys()):
        print "%s" % (sdk.platforms[key].name)

def list_projects():
    for key in sorted(sdk.projects.iterkeys()):
        print "%s ==> %s" % (sdk.projects[key].name, sdk.projects[key].path)

def list_fsets(options):
    if options.platform_name not in sdk.platforms:
        print >> sys.stderr, _("%s: is not a valid platform name") % options.platform_name
        sys.exit(1)
    for key in sorted(sdk.platforms[options.platform_name].fset.iterkeys()):
        print "%s" % (sdk.platforms[options.platform_name].fset[key].name)

def list_pkgs(options):
    if options.platform_name not in sdk.platforms:
        print >> sys.stderr, _("%s: is not a valid platform name") % options.platform_name
        sys.exit(1)

    def get_fset_pkgs(platform, fset, seen_fsets = []):
        try:
            pkgs = []
            for dep in platform.fset[fset]["deps"]:
                if dep in seen_fsets:
                    # already processed, either as a previous dep or because
                    # of a dep loop
                    continue
                seen_fsets += [dep]
                pkgs += get_fset_pkgs(platform = platform, fset = dep, seen_fsets = seen_fsets)
            pkgs += sdk.platforms[options.platform_name].fset[fset]["pkgs"]
            return pkgs
        except KeyError:
            print >> sys.stderr, _("%s: is not a valid fset name in this platform") % f
            sys.exit(1)

    pkgs = []
    for f in options.fset_names:
        pkgs += get_fset_pkgs(platform = sdk.platforms[options.platform_name], fset = f)
    print " ".join(pkgs)

def list_sources_files(options):
    if options.platform_name not in sdk.platforms:
        print >> sys.stderr, _("%s: is not a valid platform name") % options.platform_name
        sys.exit(1)
    path = os.path.join(sdk.platforms[options.platform_name].path, 'sources')
    for p in os.listdir(path):
        print os.path.join(path, p)


def list_targets(options):
    for key in (sdk.projects[options.project_name].targets.iterkeys()):
        print "%s" % (sdk.projects[options.project_name].targets[key].name)

def create_project(options):
    if options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s already exist!") % (options.project_name)
        sys.exit(1)
    if options.platform_name not in sdk.platforms:
        print >> sys.stderr, _("%s: is not a valid platform name") % options.platform_name
        sys.exit(1)
    cwd = os.getcwd()
    if cwd.find(options.project_path) == 0:
	    print >> sys.stderr, _("The project path can not be part of the current working directory")
	    sys.exit(1)
    proj = sdk.create_project(options.project_path, options.project_name, options.project_desc, sdk.platforms[options.platform_name], options.use_rootstrap)
    proj.install()

def delete_project(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    sdk.delete_project(options.project_name)

def umount_project(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    for target in sdk.projects[options.project_name].targets:
        sdk.projects[options.project_name].targets[target].umount()
    sdk.projects[options.project_name].umount()

def umount_target(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    if not options.target_name in sdk.projects[options.project_name].targets:
        print >> sys.stderr, _("Target %s does not exist") % (options.project_name)
        sys.exit(1)
    sdk.projects[options.project_name].targets[options.target_name].umount()

def run_project(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    sys.exit(sdk.projects[options.project_name].chroot(options.run_command))

def run_target(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    if not options.target_name in sdk.projects[options.project_name].targets:
        print >> sys.stderr, _("Target %s does not exist") % (options.project_name)
        sys.exit(1)
    sys.exit(sdk.projects[options.project_name].targets[options.target_name].chroot(options.run_command))

def update_project(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    sdk.projects[options.project_name].update()
    
def create_target(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    if re.search(r'\W', options.target_name):
        print >> sys.stderr, _("Target names can only contain alpha/numeric characters")
        sys.exit(1)
    target = sdk.projects[options.project_name].create_target(options.target_name, options.use_rootstrap)

def delete_target(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    proj = sdk.projects[options.project_name]
    if not options.target_name in proj.targets:
        print >> sys.stderr, _("Target %s does not exist") % (options.target_name)
        sys.exit(1)
    proj.delete_target(options.target_name)

def update_target(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    proj = sdk.projects[options.project_name]
    if not options.target_name in proj.targets:
        print >> sys.stderr, _("Target %s does not exist") % (options.target_name)
        sys.exit(1)
    proj.targets[options.target_name].update()
    
def install_fset(options):
    if options.platform_name:
        print _("Ignoring Plaform name %s") % (options.platform_name)
        print _("Using %s") % (sdk.projects[options.project_name].platform.name)
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    platform_name = sdk.projects[options.project_name].platform.name
    if not options.target_name in sdk.projects[options.project_name].targets:
        print >> sys.stderr, _("Target %s does not exist") % (options.target_name)
        sys.exit(1)
    for f in options.fset_names:
        if not f in sdk.platforms[platform_name].fset:
            print >> sys.stderr, _("Feature set %s does not exist") % f
            sys.exit(1)
    if platform_name not in sdk.platforms:
        print >> sys.stderr, _("%s: is not a valid platform name") % platform_name
        sys.exit(1)
    target = sdk.projects[options.project_name].targets[options.target_name]
    fsets = sdk.platforms[platform_name].fset
    for f in options.fset_names:
        fset = sdk.platforms[platform_name].fset[f]
        target.installFset(fset, fsets = fsets, debug_pkgs = options.debug)
#FIXME
def add_repo(options):
    if not options.project_name in sdk.projects:
        print >> sys.stderr, _("Project %s does not exist") % (options.project_name)
        sys.exit(1)
    if not options.target_name in sdk.projects[options.project_name].targets:
        print >> sys.stderr, _("Target %s does not exist") % (options.target_name)
        sys.exit(1)
    project_path = sdk.projects[options.project_name].path
    target_fs_path = os.path.join(project_path, "targets", options.target_name, "fs")
    repo_path = os.path.join(target_fs_path, "etc/yum.repos.d")
    repo_file = os.path.join(repo_path, "%s.repo" % options.repo_name)
    if os.path.exists(repo_path):
        repo_file_handle = open(repo_file, 'w')
        repo_file_handle.write("[%s]\n" % options.repo_name)
        repo_file_handle.write("name=%s\n" % options.repo_name)
        repo_file_handle.write("enabled=1\n")
        repo_file_handle.write("failovermethod=priority\n")
        repo_file_handle.write("baseurl=%s\n" % options.repo_url)
        repo_file_handle.close()
    else:
        print _("Path %s Does not exist") % repo_path    
    

def create_image(options):
    proj = sdk.projects[options.project_name]
    if options.cmd == "create-live-usb":
        proj.create_live_usb(options.target_name, options.image_name)
    elif options.cmd == "create-live-usbrw":
        proj.create_live_usb(options.target_name, options.image_name, 'EXT3FS')
    elif options.cmd == "create-nfslive-usb":
        proj.create_nfslive_usb(options.target_name, options.image_name)
    elif options.cmd == "create-install-usb":
        proj.create_install_usb(options.target_name, options.image_name)
    elif options.cmd == "create-live-iso":
        proj.create_live_iso(options.target_name, options.image_name)
    elif options.cmd == "create-nfslive-iso":
        proj.create_nfslive_iso(options.target_name, options.image_name)
    elif options.cmd == "create-install-iso":
        proj.create_install_iso(options.target_name, options.image_name)
    elif options.cmd == "create-nand":
        proj.create_NAND_image(options.target_name, options.image_name)

def chroot_project(options):
    proj = sdk.projects[options.project_name]
    proj.mount()
    os.system("chroot %s su -" % (proj.path))
    
def chroot_target(options):
    target = sdk.projects[options.project_name].targets[options.target_name]
    target.mount()
    os.system("chroot %s su -" % (target.path))

def save_project(options):
    project = sdk.save_project(options.project_name, options.file_name)

def load_project(options):
    project = sdk.load_project(options.project_name, options.project_path, options.file_name)

def print_exc_plus(type, value, tb):
    # From Python Cookbook 2nd Edition.  FIXME: Will need to remove this at
    # some point, or give attribution.
    # This is a modified version of recipe 8.6
    """ Print the usual traceback information, followed by a listing of
        all the local variables in each frame.
    """
    while tb.tb_next:
        tb = tb.tb_next
    stack = []
    f = tb.tb_frame
    while f:
        stack.append(f)
        f = f.f_back
    stack.reverse()
    traceback.print_exception(type, value, tb)
    print _("Locals by frame, innermost last")
    for frame in stack:
        print
        print _("Frame %s in %s at line %s") % (frame.f_code.co_name,
                                             frame.f_code.co_filename,
                                             frame.f_lineno)
        for key, value in frame.f_locals.items():
            print "\t%20s = " % key,
            # we must _absolutely_ avoid propagating exceptions, and str(value)
            # COULD cause any exception, so we MUST catch any...:
            try:
                print value
            except:
                print _("<ERROR WHILE PRINTING VALUE>")
    traceback.print_exception(type, value, tb)

def findExe(exe_name, env=None):
    if env is None:
        env = os.environ
    if 'PATH' in env:
        env_list = env['PATH'].split(os.pathsep)
    else:
        print _("Error: No 'PATH' environment variable defined")
        sys.exit(1)
    for dirname in env_list:
        file_name = os.path.join(dirname, exe_name)
        # FIXME: Should really check to see if it is executable, but for now
        # assume if it is in the path it is executable
        if os.path.exists(file_name):
            return True
    return False

def verifyExes():
    dist = "distribution.%s" %  mic_cfg.config.get('general', 'distribution')
    if not mic_cfg.config.has_section(dist):
        print _("Unsupported distribution: %s") % dist
        sys.exit(1)
    required_exes = mic_cfg.config.get(dist, 'required_exes')
    exe_list = required_exes.split()
    exes_found = True
    for exe_name in exe_list:
        if not findExe(exe_name):
            print _("Error: Could not find the executable: '%s' in the PATH") % exe_name
            exes_found = False
    if not exes_found:
        print _("Without the executable(s) listed, image-creator will fail to operate properly.")
        sys.exit(1)

def setEnvironmentVariables():
    for key, value in ENVIRONMENT_VARS.iteritems():
        os.environ[key] =  value

if __name__ == '__main__':
    if debug: sys.excepthook = print_exc_plus
    sys.exit(main())
