#!/usr/bin/env python
#
# grubmenu
# 
# grubmenu is the python script which creates the menu.lst file of GNU GRUB
# automatically based on the information on a configuration file.
#
# configuration file is /etc/grubmenu.conf
#
# Copyright (c) 2003 by kaepapa <kaepapa@kaepapa.dip.jp>
# 
# 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; either version 2 of the License, or
# (at your option) any later version.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.

import sys
import os
import re
import gettext

from grubmenu.common import utils
from grubmenu.common import constants
from grubmenu.common import config

try:
    from optik import OptionParser
except:
    from optparse import OptionParser

from os.path import *

from grubmenu import ui_default
from grubmenu.common import create_menu

## An exception class in case a kernel image is not found.
class noExistVMImage(Exception):
    pass

## An exception class in case root device and/or boot directroy device is not found.
class notFoundDevice(Exception):
    pass

## An exception class in case grubmenugui file is not found.
class notFoundGUI(Exception):
    pass

## Initialization of grubmenu
# This function searches the various devices needed by grubmenu.
#
# conf: Class of config
#
# return: boolean

def init_dev(conf):
    # Starting messeage
    print _("Starting configuration of grubmenu...\n")

    # Search for GRUB directory
    conf.GRUB_DIR = utils.search_dir(constants.GRUB_DIRS)

    if conf.GRUB_DIR == "":
        print _("\nNot found GRUB directory...\n"
                "GRUB seems not to install this system. Processing is stopped.\n"
                "Please change this script, when you have installed."
                )
        return 1
    else:
        print _("Found GRUB directory... :") + conf.GRUB_DIR

    # Search for root device
    try:
        __tmp_root_dev = utils.search_dev('/')
        if re.match("^/dev/.*", __tmp_root_dev) != None:
            conf.ROOT_DEV = __tmp_root_dev
    except:
        pass
    
    if conf.ROOT_DEV == "":
        print _("Not found root device.")
        ans = raw_input(_("\nPlease input the root(\"/\") device name of your system (ex. /dev/hda1) :"))
        if re.match("^/dev/.*",ans) != None:
            conf.ROOT_DEV = ans
        else:
            print _("\nNot found root device.\n"
                    "Configuration of grubmenu is aborted..."
                    )
            return 1

    print _("Set the root device name :") + conf.ROOT_DEV
    
    # Search for GRUB root device
    try:
        __tmp_grub_root_dev = utils.search_dev('/boot')
        if re.match("^/dev/.*", __tmp_grub_root_dev) != None:
            conf.GRUB_ROOT_DEV = __tmp_grub_root_dev
    except:
        pass

    if conf.GRUB_ROOT_DEV == "":
        conf.GRUB_ROOT_DEV = conf.ROOT_DEV

    ans = raw_input(_("\nIs the GRUB root device(device of existing /boot/grub) of your system all right bellow? : ")\
                    + conf.GRUB_ROOT_DEV + " (Y/n)")
    if ans == "n":
        ans = raw_input(_("\nPlease input the GRUB root device (device of existing /boot/grub) "
                          "name of your system (ex. /dev/hda1) :"))
        if re.match("^/dev/.*",ans) != None:
            conf.GRUB_ROOT_DEV = ans
        else:
            print _("\nNot found GRUB root device of your system.\n"
                    "Configration of grubmenu is aborted."
                    )
            return 1

    print _("Set the GRUB root device name of your system :") + conf.GRUB_ROOT_DEV

    # Preservation to a setting file
    conf.writeconf()

    return 0

## get Dist name function
# This function is get distributions name on this system
#
# conf: Class of config
#
# return: boolean

def getDistName(conf):
    for ver_file in constants.VER_FILES:
        if isfile(ver_file[0]):
            conf.DIST_NAME = ver_file[1]
            break
            
    if conf.DIST_NAME == "":
        conf.DIST_NAME = "Linux"

    conf.writeconf()
    
    return 0
        
## Main function
# This function acquires an option, distributes to various processings, and creates menu.lst.
#
# return: boolean

def main():
        
    # Command-line option parser
    parser = OptionParser(usage = "%prog [option]",
                          version = constants.VERSION)

    parser.add_option('-c','--config',
                      action = "store_true", dest = "config_ui",
                      help = "This option is created with a CUI interface.")
    parser.add_option('-g','--guiconfig',
                      action = "store_true", dest = "config_gui",
                      help = "This option is created with a GUI interface.")
    parser.add_option('-s','--swsusp',
                      action = "store_true", dest = "swsusp",
                      help = "This option is changes default boot kernel in menu.lst on suspend of swsusp.")
    parser.add_option('-d','--display',
                      action = "store_true", dest = "display",
                      help = "This option only displays without changing menu.lst.")
        
    (options, args) = parser.parse_args()

    

    conf = config.config()
    if (conf.ROOT_DEV == ''):
        if init_dev(conf) == 1:
            raise notFoundDevice

    if conf.DIST_NAME == '':
        getDistName(conf)

    if options.config_ui:
        if ui_default.cui_config(conf) == 0:
            print _("\nConfigration complete.\n")

            ans = raw_input(_("Is menu.lst created continuously?(y/N) :"))
            if utils.check_answer_yes(ans) == 1:
                sys.exit(0)
        else:
            print _("\nConfigration missing.")
            sys.exit(1)

    elif options.config_gui:
        if isfile(dirname(sys.argv[0])+"/grubmenugui"):
            os.system(dirname(sys.argv[0])+"/grubmenugui")
        else:
            raise notFoundGUI
            
        sys.exit(0)

    elif options.swsusp:
        if conf.SWSUSP == '':
            now_img = 'vmlinuz-' + os.uname()[2]
            if now_img != conf.DEFAULT:
                conf.SWSUSP = conf.DEFAULT
                conf.DEFAULT = now_img
                conf.STIME = conf.TIME
                conf.TIME = "10"
                conf.writeconf()
        else:
            conf.DEFAULT = conf.SWSUSP
            conf.SWSUSP = ""
            conf.TIME = conf.STIME
            conf.STIME = ""
            conf.writeconf()

    elif options.display:
        st = create_menu.write_menu(conf)
        # print _("\nThis menu.lst was displayed by grubmenu\n")
        print st.getvalue()
        sys.exit(0)

    st = create_menu.write_menu(conf)
    
    try:
        f = file(conf.GRUB_DIR+'menu.lst','w')
        f.write(st.getvalue())
    finally:
        f.close()
        
    print _("\nThe menu.lst was created.\n")

    return 0
    
if __name__ == '__main__':
    # gettextized
    gettext.install('grubmenu')
    
    try:
        main()
    except (KeyboardInterrupt,EOFError):
        print _("\ngrubmenu: Aborting due to user interrupt.\n")
    except noExistVMImage:
        print _("\ngrubmenu: No Exist vmlinuz image in boot directory.\n")
    except notFoundDevice:
        print _("\ngrubmenu: Abort...\n")
    except notFoundGUI:
        print _("\ngrubmenu: This environment is installed as the nogui option.\n"
                "This option cannot be used.")
    sys.exit(0)
    













