#!/usr/bin/python
#
# snake-install - install a tree using snake
#
# Copyright 2006, 2007 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use, modify,
# copy, or redistribute it subject to the terms and conditions of the GNU
# General Public License v.2.  This program is distributed in the hope that it
# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
# implied warranties 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., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
# trademarks that are incorporated in the source code or documentation are not
# subject to the GNU General Public License and may only be used or replicated
# with the express permission of Red Hat, Inc. 
#

import os, sys
import optparse
import snake.install
import snake.log
import rpmUtils.arch
from urlgrabber import progress

interactive_prog = 'snake-install-tui'

# TODO - move the following into the man page
#def usage():
#    '''Give usage info for this program'''
#    print '''usage: %s URI [kickstart]
#    Grabs boot images from URI, modifies bootloader config, and reboots into
#    the installer. If you don't have a URI, try %s
#''' % (os.path.basename(sys.argv[0]),interactive_prog)

def setup_option_parser():
    parser=optparse.OptionParser(usage="snake-install [options] URI [kickstart]")
    parser.add_option("-i", "--interactive",
                action="store_true", dest="interactive", default=False,
                help="Run in interactive mode, will prompt for options")
    parser.add_option("-a", "--arch",
                action="store", dest="arch", default=rpmUtils.arch.getBaseArch(),
                help="Only include trees of specified architecture (default: %default)")
    parser.add_option("-c", "--cmdline",
                action="store", dest="cmdline", default="",
                help="Specify command-line arguments to pass to the installer")
    parser.add_option("-v", "--verbose",
                action="store_true", dest="verbose", default=False,
                help="Output extra information")
    return parser

if __name__ == '__main__':

    parser = setup_option_parser()
    (opt, args) = parser.parse_args()

    # interactive mode requested?
    if opt.interactive:
        # FIXME - should interactive get sys.argv?
        if os.path.exists(interactive_prog):
            os.execl(interactive_prog,'')
        else:
            os.execlp(interactive_prog,'')

    # Set up logging
    log = snake.log.setup_logger(opt.verbose and snake.log.DEBUG or snake.log.INFO)

    # Examine cmdline positional parameters
    uri = None
    ksfile = None
    if len(args) <= 0:
        parser.error("You need to give some URI to install from")
        sys.exit(1)
    else:
        uri = args[0]
        # kickstart file given?
        if len(args) >= 2:
            ksfile = args[1]

    # dictionary to hold fetch_and_prep arguments
    fpargs = dict()

    # Read supplied kickstart file
    if ksfile:
        # TODO - support http/ftp URI's?
        if os.path.isfile(ksfile):
            ks = open(ksfile, 'r')
            fpargs['ksdata'] = ks.read()
            ks.close()
        else:
            parser.error("Unable to open '%s'" % ksfile)
            sys.exit(1)

    # Supply any cmdline parameters provided by user
    if opt.cmdline:
        fpargs["args"] = opt.cmdline

    # Are any arch overrides needed?
    # FIXME: this sort of monkeying with arch should really happen in the 
    # client libs, rather than each app..
    from snake.machineinfo import isParaVirt
    if isParaVirt():
        '''paravirt guests will need xen boot images'''
        fpargs["arch"] = "xen"
    else:
        fpargs["arch"] = opt.arch

    if fpargs["arch"] == 'ppc' and os.uname()[4] == 'ppc64':
        fpargs["arch"] = 'ppc64'

    # Build a progress meter callback
    fpargs['progress_callback'] = progress.TextMeter()

    # Fetch and prep install images
    try:
        snake.install.fetch_and_prep(uri,**fpargs)
        t = snake.uri.uri_to_tree(uri)
        if t.arch.startswith('ppc'):
            print "FIXME: you need to run ybin to update the bootloader now"
        print "Done. You may now reboot your system to start the install."
    except Exception, e:
        # FIXME - need more appropriate ERROR handling other than True/False
        #log.exception("Exception")
        print "Failed! Aiee! Maybe you need to be root?"
