#!/usr/bin/env python
#
#   ConVirt   -  Copyright (c) 2008 Convirture Corp.
#   ======
#
# ConVirt is a Virtualization management tool with a graphical user
# interface that allows for performing the standard set of VM operations
# (start, stop, pause, kill, shutdown, reboot, snapshot, etc...). It
# also attempts to simplify various aspects of VM lifecycle management.
#
#
# This software is subject to the GNU General Public License, Version 2 (GPLv2)
# and for details, please consult it at:
#
#    http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
# 
#
# author : Jd <jd_jedi@users.sourceforge.net>
#

# Module containing classes for VM Settings and handlers

import re,pprint, traceback
import types
import os, sys,copy
import gtk, gtk.glade, gobject

from convirt.client.VMSettings import BootPage, GeneralPage
from convirt.client.VMSettings import SettingsNotebook,VMNotebook
from convirt.client.VMSettings import VMSettingsDlg, VMDiskEditDlg

from convirt.client.ui_utils import *

from convirt.client.XenUI import gladefile

# Augment the disk type and device types specific to Xen
class XenDiskEditDlg(VMDiskEditDlg):
    def __init__(self,
                 storage_manager,
                 disk_entry,
                 is_remote, 
                 managed_node=None,
                 server_pool=None,
                 mode = "ADD",
                 parent_mode = None,
                 parent=None ):
        VMDiskEditDlg.__init__(self,
                               storage_manager,
                               disk_entry,
                               is_remote, 
                               managed_node,
                               server_pool,
                               mode,
                               parent_mode,
                               parent )
    def get_device_map(self):
        base_map = VMDiskEditDlg.get_device_map(self)
        #augment the map
        base_map["xvda"] = "xvda"
        base_map["xvdb"] = "xvdb"
        base_map["xvdc"] = "xvdc"

        return base_map
    

    def get_disk_type_map(self):
        base_map = VMDiskEditDlg.get_disk_type_map(self)
        # augment the map
        #base_map["tap:aio"] = "tap:aio"
        #base_map["tap:qcow"] = "tap:qcow"
        #base_map["tap:vmdk"] = "tap:vmdk"

        return base_map



class XenGeneralPage(GeneralPage):
    def __init__(self, context):
        GeneralPage.__init__(self, context)


    def get_disk_edit_dlg(self, disk, is_remote,
                          managed_node, server_pool, mode,  parent_mode,
                          parentwin):
        return XenDiskEditDlg(self.storage_manager,
                              disk, is_remote, managed_node,
                              server_pool, mode, parent_mode,parentwin)




class XenBootPage(BootPage):
    def __init__(self, context):
        BootPage.__init__(self, context)
        

    def ui_init(self, context):
        BootPage.ui_init(self, context)
        # construct and add required widgets.
        # and update the widgets list
        table = self.widgets.vm_boot_param_table
        rows = table.get_property("n-rows")
        cols = table.get_property("n-columns")
        
        # add 1 rows to the table and move exiting widgets down.
        table.resize(rows+1, cols)
        self.move_down(table, 1)

        # add the widgets
        xen_wtree =  gtk.glade.XML(gladefile, "boot_widget_container")

        # init_widget is additive : Watch for name collision
        self.init_widgets(xen_wtree, ["boot_loader_check_btn",
                                      "boot_loader_entry",
                                      "boot_widget_table"])


        self.dlg = xen_wtree.get_widget("boot_widget_container")
        self.dlg_table = self.widgets.boot_widget_table
        row = 0

        self.dlg_table.remove(self.widgets.boot_loader_check_btn)
        self.dlg_table.remove(self.widgets.boot_loader_entry)

        table.attach(self.widgets.boot_loader_check_btn,0, 1,row, row+1)
        table.attach(self.widgets.boot_loader_entry,1, 2,row, row+1)


        # setup handler
        xen_wtree.signal_connect("on_boot_loader_toggled",
                             self.on_boot_loader_toggled)


        self.dlg.hide()
        self.dlg.destroy()

    def on_boot_loader_toggled(self, widget):
        use_boot = widget.get_active()
        self.widgets.vm_kernel_entry.set_sensitive(not use_boot)
        self.widgets.vm_ramdisk_entry.set_sensitive(not use_boot)
        self.widgets.boot_loader_entry.set_sensitive(use_boot)

    def move_down(self, table, num_rows):
        for c in table.get_children():
            (left, right, top, bottom) =  \
                   table.child_get_property(c,"left-attach"),\
                   table.child_get_property(c,"right-attach"), \
                   table.child_get_property(c,"top-attach"),\
                   table.child_get_property(c,"bottom-attach")
            table.remove(c)
            table.attach(c, left, right, top + num_rows, bottom+num_rows)

    def get_widgets_to_disable(self, mode):
        base_widgets = BootPage.get_widgets_to_disable(self,mode)
        if mode in ["EDIT_VM_INFO",]:
            for widget in ["boot_loader_check_btn",
                           "boot_loader_entry",
                             ]:
                base_widgets.append(self.widgets[widget])

        return base_widgets



    def scatter(self, context):
        BootPage.scatter(self,context)
        mode = context.mode
        vm_config = context.get("vm_config")
        if vm_config and mode != "EDIT_VM_INFO" :
            boot_loader = vm_config.get("bootloader")
            if boot_loader :
                use_boot_loader = True
            else:
                use_boot_loader = False
            self.widgets.vm_kernel_entry.set_sensitive(not use_boot_loader)
            self.widgets.vm_ramdisk_entry.set_sensitive(not use_boot_loader)
            self.widgets.boot_loader_entry.set_sensitive(use_boot_loader)
            set_value(self.widgets.boot_loader_check_btn, use_boot_loader)
            if boot_loader :
                set_value(self.widgets.boot_loader_entry, boot_loader)
            else:
                    set_value(self.widgets.boot_loader_entry, '/usr/bin/pygrub')
        if vm_config and mode == "EDIT_VM_INFO":
            vm_info = self.context.vm_info
            if vm_info:
                for widget, config_attr in (("boot_loader_entry",
                                             "bootloader"),
                                            ):
                    set_value(self.widgets[widget], vm_info[config_attr])
                  
    def gather(self, context):
        BootPage.gather(self,context)
        mode = context.mode
        vm_config = context.get("vm_config")
        if vm_config and mode != "EDIT_VM_INFO":
            use_boot_loader = get_value(self.widgets.boot_loader_check_btn)
            if use_boot_loader:
                vm_config["bootloader"] = get_value(self.widgets.boot_loader_entry)
                vm_config["kernel"] = ""
                vm_config["ramdisk"] = ""
            else:
                vm_config["bootloader"] = ""



class XenNotebook(VMNotebook):
    def __init__(self, context):
        VMNotebook.__init__(self, context)
        
    def get_boot_page(self):
        return XenBootPage(self.context)

    def get_gen_page(self):
        return XenGeneralPage(self.context)

class XenSettingsNotebook(SettingsNotebook):
    def __init__(self, context):
        SettingsNotebook.__init__(self, context)

    def get_vm_notebook_page(self):
        return XenNotebook(self.context)

class XenSettingsDlg(VMSettingsDlg):
    def __init__(self, mode,ctx, parent_win = None):
        VMSettingsDlg.__init__(self, mode,ctx, parent_win)

    def get_settings_notebook(self):
        return XenSettingsNotebook(self.context)









