#!/usr/bin/python2
#
# Copyright 2007 Fedora Unity
#
# Jonathan Steffan <jon a fedoraunity.org>
# Jeroen van Meeuwen <kanarip a fedoraunity.org>
#
# 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 only
#
# 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 Library 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 pdb
#pdb.set_trace()

import logging
import os
import sys

from rhpl.translate import _, N_
import rhpl.translate as translate

# This is development
sys.path.append(sys.path[0])

if os.access(sys.path[0] + "/../pungi/", os.R_OK):
    sys.path.append(sys.path[0] + "/../pungi/")

if os.access("/usr/lib/anaconda-runtime/", os.R_OK):
    sys.path.append("/usr/lib/anaconda-runtime/")
else:
    print >> sys.stderr, _("Cannot find anaconda-runtime in /usr/lib/anaconda-runtime")
    sys.exit(1)


from optparse import OptionParser
import revisor.logger
import revisor.base
import revisor.cfg

if os.geteuid() != 0:
    print >> sys.stderr, _("This tool has to run with root privileges. Aborting")
    sys.exit(1)

# Detect earlier if we are able to run GUI
hasDisplay = True
try:
    import gtk
    import gtk.glade
    import gobject
    import gtk.gdk as gdk
except:
    hasDisplay = False


# Parse the options passed to us from runtime cli
parser = OptionParser()

##
## Runtime Options
parser.add_option("--cli", dest="revisorUseCLI",
        action="store_true", default=False, help=_("Use the CLI rather then GUI"))
parser.add_option("--gui", dest="revisorUseGUI",
        action="store_true", default=False, help=_("Force Revisor to use the GUI. Does not fallback to CLI and thus shows GUI related errors"))

##
## Configuration Options
parser.add_option("--kickstart", dest="kickstart_file",
        action="store", default="", help=_("Use kickstart file"), metavar="[kickstart file]")
parser.add_option("--config", dest="revisor_config",
        action="store", default="", help=_("Revisor configuration file to use"), metavar="[config file]")
parser.add_option("--model", dest="revisor_model",
        action="store", default=None, help=_("Model to use for composing"), metavar="[model]")

##
## Installation Media Options
parser.add_option("--cd", dest="media_installation_cd",
        action="store_true", default=False, help=_("Create Installation Media CDs"))
parser.add_option("--dvd", dest="media_installation_dvd",
        action="store_true", default=False, help=_("Create Installation Media DVDs"))
parser.add_option("--unified", dest="media_installation_unified",
        action="store_true", default=False, help=_("Create Unified ISO from install tree"))
parser.add_option("--install-tree", dest="media_installation_tree",
        action="store_true", default=False, help=_("Build install tree. [Inferred when using --cd or --dvd]"))

##
## Live Media Options
parser.add_option("--usb-thumb", dest="media_live_thumb",
        action="store_true", default=False, help=_("Create Live Media Thumb Drive Image"))
parser.add_option("--usb-hd", dest="media_live_hd",
        action="store_true", default=False, help=_("Create Live Media Hard Disk Image"))
parser.add_option("--optical", dest="media_live_optical",
        action="store_true", default=False, help=_("Create Live Media CD/DVD"))

##
## Logging Options
parser.add_option("--debug", dest="loglevel_debug",
        action="store_true", default=False, help=_("Enable debugging level"))

# FIXME
# Disabled cobbler and delta support for 2.0.4.x release
##
## Cobbler Options
#parser.add_option("--add-distro", dest="cobbler_add_distro",
#        action="store", default="", help=_("Add compose to a Cobbler server as a distribution option."), metavar="[distro-name]")
#parser.add_option("--add-profile", dest="cobbler_add_profile",
#        action="store", default="", help=_("Add compose options as a Profile to a Cobbler server."), metavar="[profile-name]")

##
## Delta ISO Generation
#parser.add_option("--delta", dest="delta_old_image",
#        action="store", default="", help=_("Generate a delta ISO image."), metavar="[old-iso-image]")

# Parse Options
(options,args) = parser.parse_args()

if not hasDisplay:
    options.revisorUseCLI = True
    options.revisorUseGUI = False
    print "No valid display found, failing over to CLI interface..."

# Set loglevel
if options.loglevel_debug:
    loglevel = logging.DEBUG
else:
    loglevel = logging.INFO

# Initialize logger
log = revisor.logger.Logger(debuglevel = loglevel)

# Initialize Configuration Store
cfg = revisor.cfg.ConfigStore(options, log)

# FIXME: ? We need to know this to be able to use these options when setting up the log ?

# Well, the thing is, the logger uses things from the config and the config uses things from the log... ;-)
# - log inits and is instance
# - cfg inits and is instance
# - log should get a pointer to cfg
# - cfg should know what mode we're in, so that when errors are logged because of some runtime error during the
#   actual initialisation, the logger can test what mode we're in using the cfg store.
# - then setup the cfg in a way that sets up all the configuration and it can log it's errors

# Let the logger know about cfg
log.set_config(cfg)

# Set the cfg modes because... well... if they're not there logger b0rks
cfg.revisorUseGUI = options.revisorUseGUI
cfg.revisorUseCLI = options.revisorUseCLI

# Then really setup the ConfigStore
cfg.setup_cfg()

# Setup base
base = revisor.base.RevisorBase(cfg = cfg, log = log)

# Split into either running CLI, or GUI
if options.revisorUseCLI:
#    print >> sys.stdout, "Runtime parameter to run CLI mode set"
    import revisor.cli
    log.info(_("Running Revisor in CLI mode as specified by command line options"))
    revisorBase = revisor.cli.RevisorCLI(base, log)

elif options.revisorUseGUI:
    import gtk
    import gtk.glade
    import gobject
    import gtk.gdk as gdk
    import revisor.gui
    log.info(_("Running Revisor in GUI mode as specified by command line options"))
    revisorBase = revisor.gui.RevisorGUI(base, log)

else:
    # No runtime options were set, so try the GUI and fall back to CLI
    try:
        cfg.revisorUseGUI = True
        cfg.revisorUseCLI = False
        import gtk
        import gtk.glade
        import gobject
        import gtk.gdk as gdk
    except:
        cfg.revisorUseGUI = False
        cfg.revisorUseCLI = True

    if cfg.revisorUseGUI:
        import revisor.gui
        revisorBase = revisor.gui.RevisorGUI(base, log)
    else:
        import revisor.cli
        revisorBase = revisor.cli.RevisorCLI(base, log)

# Check what features we have installed
# Let's see how fucking cool we can make this

# Add this to the init of cfg
#
#plugins = ['cobbler','delta']
#
#for plugin in plugins:
#    try:
#        cfg.plugins[plugin] = True
#        exec("import revisor.%s" % plugin)
#    except:
#        cfg.plugins[plugin] = False

# Check for cobbler support
#try:
#    cfg.hasCobbler = True
#    import revisor.cobbler
#except:
#    cfg.hasCobbler = False

# Check for delta support
#try:
#    cfg.hasDelta = True
#    import revisor.delta
#except:
#    cfg.hasDelta = False

# Check we have the needed sub packages installed for options given

#if not cfg.hasCobbler:
##if not cfg.plugins['cobbler']:
#    if len(options.cobbler_add_distro) > 0 or len(options.cobbler_add_profile) > 0:
#        log.error(_("Revisor Cobbler plugin options specified, but no cobbler module was found. Install revisor-cobbler."), recoverable = False)

# And:

#if not cfg.hasDelta:
#if not cfg.plugins['delta']:
#    if len(options.delta_old_image) > 0:
#        log.error(_("Delta image creation specified, but no delta module found. Install revisor-delta."), recoverable = False)
#elif len(options.delta_old_image) > 0:
#    if not os.access(options.delta_old_image, os.R_OK):
#        log.error(_(("%s could not be found, please specify a valid ISO.") % (options.delta_old_image)), recoverable = False)
#    if not cfg.media_installation_cd and not cfg.media_installation_dvd:
#        log.error(_("To be able to create a delta, you need to generate a new ISO image. Add --dvd or --cd."), recoverable = False)

#if len(options.delta_old_image) > 0 and not cfg.hasDelta:
#    log.info(_("Delta image generation selected, but no delta module found. Install revisor-delta."))
#    sys.exit(1)
#elif len(options.delta_old_image) > 0 and cfg.hasDelta:
#    if not os.access(options.delta_old_image, os.R_OK):
#        log.info(_(("%s could not be found, please specify a valid ISO.") % (options.delta_old_image)))
#        sys.exit(1)
#    if not cfg.media_installation_cd and not cfg.media_installation_dvd:
#        log.info(_("To be able to create a delta, you need to generate a new ISO image. Add --dvd or --cd."))
#        sys.exit(1)


# Direct things for revisorBase from here

# Let our base now what mode we are in
base.set_mode(revisorBase)

# Then really setup the ConfigStore
cfg.setup_cfg()

# Run
log.debug(_("Running main routine..."))
revisorBase.run()
