import isys
import os
from installclass import InstallClass
from installclass import FSEDIT_CLEAR_LINUX
from installclass import FSEDIT_CLEAR_ALL
import sys
import string

class Kickstart(InstallClass):

   def doRootPw(self, args):
       (args, extra) = isys.getopt(args, '', [ 'iscrypted' ])

       isCrypted = 0
       for n in args:
           (str, arg) = n
           if (str == '--iscrypted'):
               isCrypted = 1

       if len(extra) != 1:
           raise ValueError, "a single argument is expected to rootPw"

       InstallClass.doRootPw(self, extra[0], isCrypted = isCrypted)
       self.addToSkipList("accounts")

   def doAuthconfig(self, args):
       (args, extra) = isys.getopt(args, '',
               [ 'enablenis', 'nisdomain=', 'nisserver=', 'useshadow',
                 'enablemd5' ])

       useNis = 0
       useShadow = 0
       useMd5 = 0
       nisServer = None
       nisDomain = None
       nisBroadcast = 0

       for n in args:
           (str, arg) = n
           if (str == '--enablenis'):
               useNis = 1
           elif (str == '--useshadow'):
               useShadow = 1
           elif (str == '--enablemd5'):
               useMd5 = 1
           elif (str == '--nisserver'):
               nisServer = arg
           elif (str == '--nisdomain'):
               nisDomain = arg

       if useNis and not nisServer: nisBroadcast = 1

       self.setAuthentication(useShadow, useMd5, useNis, nisDomain,
                              nisBroadcast, nisServer)
       self.addToSkipList("authentication")

   def doLilo  (self, args):
       (args, extra) = isys.getopt(args, '',
               [ 'append=', 'location=', 'linear' ])

       appendLine = None
       location = "mbr"
       linear = 0

       for n in args:
           (str, arg) = n
           if str == '--append':
               appendLine = arg
           elif str == '--linear':
               linear = 1
           elif str == '--location':
               if arg == 'mbr' or arg == 'partition':
                   location = arg
               elif arg == 'none':
                   location = None
               else:
                   raise ValueError, ("mbr, partition or none expected for "+
                       "lilo command")

       self.setLiloInformation(location, linear, appendLine)
       self.addToSkipList("lilo")

   def doLiloCheck (self, args):
       drives = isys.hardDriveList ().keys()
       drives.sort(isys.compareDrives)
       device = drives[0]
       isys.makeDevInode(device, '/tmp/' + device)
       fd = os.open('/tmp/' + device, os.O_RDONLY)
       os.unlink('/tmp/' + device)
       block = os.read(fd, 512)
       os.close(fd)
       if block[6:10] == "LILO":
           sys.exit(0)

   def doTimezone(self, args):
       (args, extra) = isys.getopt(args, '',
               [ 'utc' ])

       isUtc = 0

       for n in args:
           (str, arg) = n
           if str == '--utc':
               isUtc = 1

       self.setTimezoneInfo(extra[0], asUtc = isUtc)

       self.addToSkipList("timezone")


   def doXconfig(self, args):
       (args, extra) = isys.getopt(args, '',
               [ 'server=', 'card=', 'monitor=', 'hsync=', 'vsync=',
                 'startxonboot', 'noprobe' ])

       if extra:
           raise ValueError, "unexpected arguments to xconfig command"

       server = None
       card = None
       monitor = None
       hsync = None
       vsync = None
       noProbe = 0
       startX = 0

       for n in args:
           (str, arg) = n
           if (str == "--noprobe"):
               noProbe = 1
           elif (str == "--server"):
               server = arg
           elif (str == "--card"):
               card = arg
           elif (str == "--monitor"):
               monitor = arg
           elif (str == "--hsync"):
               hsync = arg
           elif (str == "--vsync"):
               vsync = arg
           elif (str == "--startxonboot"):
               startX = 1

       self.configureX(server, card, monitor, hsync, vsync, noProbe,
                       startX)
       self.addToSkipList("xconfig")

   def doInstall(self, args):
       self.installType = "install"

   def doUpgrade(self, args):
       self.installType = "upgrade"

   def doNetwork(self, args):
       # nodns is only used by the loader
       (args, extra) = isys.getopt(args, '',
               [ 'bootproto=', 'ip=', 'netmask=', 'gateway=', 'nameserver=',
                 'nodns', 'hostname='])
       bootProto = "dhcp"
       ip = None
       netmask = ""
       gateway = ""
       nameserver = ""
       hostname = ""
       for n in args:
           (str, arg) = n
           if str == "--bootproto":
               bootProto = arg
           elif str == "--ip":
               ip = arg
           elif str == "--netmask":
               netmask = arg
           elif str == "--gateway":
               gateway = arg
           elif str == "--nameserver":
               nameserver = arg
           elif str == "--hostname":
               hostname = arg
       self.setNetwork(bootProto, ip, netmask, gateway, nameserver)
       if hostname != "":
           self.setHostname(hostname)

   def doLang(self, args):
       self.setLanguage(args[0])
       self.addToSkipList("language")

   def doKeyboard(self, args):
       self.setKeyboard(args[0])
       self.addToSkipList("keyboard")

   def doZeroMbr(self, args):
       if args[0] == "yes":
           self.setZeroMbr(1)

   def doMouse(self, args):
       mouseToMouse = {
            "alpsps/2" : "ALPS - GlidePoint (PS/2)",
            "ascii" : "ASCII - MieMouse (serial)",
            "asciips/2" : "ASCII - MieMouse (PS/2)",
            "atibm" : "ATI - Bus Mouse",
            "generic" : "Generic - 2 Button Mouse (serial)" ,
            "generic3" : "Generic - 3 Button Mouse (serial)" ,
            "genericps/2" : "Generic - 2 Button Mouse (PS/2)" ,
            "generic3ps/2" : "Generic - 3 Button Mouse (PS/2)" ,
            "geniusnm" : "Generic - 2 Button Mouse (PS/2)" ,
            "geniusnmps/2" : "Genius - NetMouse (PS/2)" ,
            "geniusnsps/2" : "Genius - NetScroll (PS/2)" ,
            "thinking" : "" ,
            "thinkingps/2" : "" ,
            "logitech" : "Logitech - C7 Mouse (serial, old C7 type)" ,
            "logitechcc" : "Logitech - CC Series (serial)" ,
            "logibm" : "Logitech - Bus Mouse" ,
            "logimman" : "Logitech - MouseMan/FirstMouse (serial)" ,
            "logimmanps/2" : "Logitech - MouseMan/FirstMouse (PS/2)" ,
            "logimman+" : "Logitech - MouseMan+/FirstMouse+ (serial)" ,
            "logimman+ps/2" : "Logitech - MouseMan+/FirstMouse+ (PS/2)" ,
            "microsoft" : "Microsoft - Compatible Mouse (serial)" ,
            "msnew" : "Microsoft - Rev 2.1A or higher (serial)" ,
            "msintelli" : "Microsoft - IntelliMouse (serial)" ,
            "msintellips/2" : "Microsoft - IntelliMouse (PS/2)" ,
            "msbm" : "Microsoft - Bus Mouse" ,
            "mousesystems" : "Mouse Systems - Mouse (serial)" ,
            "mmseries" : "MM - Series (serial)" ,
            "mmhittab" : "MM - HitTablet (serial)" ,
            "sun" : "Sun - Mouse"
       }

       (args, extra) = isys.getopt(args, '', [ 'device=', 'emulthree' ])
       mouseType = "none"
       device = None
       emulThree = 0

       for n in args:
           (str, arg) = n
           if str == "--device":
               device = arg
           elif str == "--emulthree":
               emulThree = 1

       if extra:
           mouseType = extra[0]

       if mouseType != "none":
           self.setMouseType(mouseToMouse[mouseType], device, emulThree)

       self.addToSkipList("mouse")

   def doReboot(self, args):
       self.addToSkipList("complete")

   def doSkipX(self, args):
       self.addToSkipList("xconfig")

   def readKickstart(self, file):
       handlers = {
                    "auth"             : self.doAuthconfig     ,
                    "authconfig"       : self.doAuthconfig     ,
                    "cdrom"            : None                  ,
                    "clearpart"        : self.doClearPart      ,
                    "device"           : None                  ,
                    "driverdisk"       : None                  ,
                    "harddrive"        : None                  ,
                    "install"          : self.doInstall        ,
                    "keyboard"         : self.doKeyboard       ,
                    "lang"             : self.doLang           ,
                    "lilo"             : self.doLilo           ,
                    "lilocheck"        : self.doLiloCheck      ,
                    "mouse"            : self.doMouse          ,
                    "network"          : self.doNetwork        ,
                    "nfs"              : None                  ,
                    "part"             : self.definePartition  ,
                    "partition"        : self.definePartition  ,
                    "raid"             : self.defineRaid       ,
                    "reboot"           : self.doReboot         ,
                    "rootpw"           : self.doRootPw         ,
                    "skipx"            : self.doSkipX          ,
                    "text"             : None                  ,
                    "timezone"         : self.doTimezone       ,
                    "upgrade"          : self.doUpgrade        ,
                    "xconfig"          : self.doXconfig        ,
                    "xdisplay"         : None                  ,
                    "zerombr"          : self.doZeroMbr        ,
                  }

       where = "commands"
       packages = []
       groups = []
       post = ""
       postInChroot = 1
       for n in open(file).readlines():
           if where == "post":
               post = post + n
           else:
               n = n[:len(n) - 1]          # chop

               args = isys.parseArgv(n)
               if not args or args[0][0] == '#': continue

               if where == "commands":
                   cmd = args[0]
                   if cmd == "%packages":
                       where = "packages"
                   elif cmd[0:5] == "%post":
                       args = isys.parseArgv(n)
                       if len(args) >= 2 and args[1] == "--nochroot":
                           postInChroot = 0
                       where = "post"
                   elif handlers[cmd]:
                       handlers[cmd](args[1:])
               elif where == "packages":
                   if n[0:5] == "%post":
                       args = isys.parseArgv(n)
                       if len(args) >= 2 and args[1] == "--nochroot":
                           postInChroot = 0
                       where = "post"
                   elif n[0] == '@':
                       n = n[1:]
                       n = string.strip (n)
                       groups.append(n)
                   else:
                       n = string.strip (n)
                       packages.append(n)

       self.setGroups(groups)
       self.setPackages(packages)
       self.setPostScript(post, postInChroot)

   def doClearPart(self, args):
       if args[0] == '--linux':
           clear = FSEDIT_CLEAR_LINUX
       elif args[0] == '--all':
           clear = FSEDIT_CLEAR_ALL
       self.setClearParts(clear)

   def defineRaid(self, args):
       (args, extra) = isys.getopt(args, '', [ 'level=', 'device=' ] )

       for n in args:
           (str, arg) = n
           if str == '--level':
               level = int(arg)
           elif str == "--device":
               raidDev = arg

       mntPoint = extra[0]
       extra = extra[1:]

       self.addRaidEntry(mntPoint, raidDev, level, extra)

   def definePartition(self, args):
       # we just set up the desired partitions -- magic in our base class
       # does the actual partitioning (no, you don't want to know the
       # details)
       size = 0
       grow = 0
       maxSize = -1
       device = None
       onPart = None

       (args, extra) = isys.getopt(args, '', [ 'size=', 'maxsize=',
                                       'grow', 'onpart=', 'ondisk=' ])

       for n in args:
           (str, arg) = n
           if str == '--size':
               size = int(arg)
           elif str == '--maxsize':
               maxSize = int(arg)
           elif str == '--grow':
               grow = 1
           elif str == '--onpart':
               onPart = arg
           elif str == '--ondisk':
               device = arg

       if len(extra) != 1:
           raise ValueError, "partition command requires one anonymous argument"

       if onPart:
           self.addToFstab(extra[0], onPart)
       else:
           self.addNewPartition(extra[0], size, maxSize, grow, device)

   def __init__(self, file):
       InstallClass.__init__(self)
       self.addToSkipList("bootdisk")
       self.addToSkipList("welcome")
       self.addToSkipList("package-selection")
       self.addToSkipList("confirm-install")
       self.addToSkipList("custom-upgrade")
       self.addToSkipList("network")
       self.setEarlySwapOn(1)
       self.partitions = []

       self.installType = "install"
       self.readKickstart(file)