import string
import os

from booty import BootyNoKernelWarning
from util import getDiskPart
from bootloaderInfo import *
import iutil

class sparcBootloaderInfo(bootloaderInfo):
    def writeSilo(self, instRoot, bl, kernelList,
                  chainList, defaultDev):

        try:
            bootDev = self.storage.mountpoints["/boot"]

            mf = '/silo.message'
            cf = "/boot/silo.conf"
            mfdir = '/boot'
            cfPath = ""
            if not os.path.isdir(instRoot + "/boot"):
                os.mkdir(instRoot + "/boot")
        except KeyError:
            bootDev = self.storage.rootDevice

            cf = "/etc/silo.conf"
            mfdir = '/etc'
            cfPath = "/boot"

        f = open(instRoot + mfdir + mf, "w+")
        f.write("Welcome to %s!\nHit <TAB> for boot options\n\n" % productName)
        f.close()
        os.chmod(instRoot + mfdir + mf, 0600)

        f = open(instRoot + cf, "w+")
        f.write("# silo.conf generated by anaconda\n\n")

        f.write("#boot=%s\n" % (bootDev.path,))
        f.write("message=%s\n" % (mf,))
        f.write("timeout=%s\n" % (self.timeout or 50))

        (name, partNum) = getDiskPart(bootDev.name, self.storage)
        partno = partNum + 1
        f.write("partition=%s\n" % (partno,))

        if self.password:
            f.write("password=%s\n" % (self.password,))
            f.write("restricted\n")

        f.write("default=%s\n" % (kernelList[0][0],))
        f.write("\n")

        rootDev = self.storage.rootDevice

        for (label, longlabel, version) in kernelList:
            kernelTag = "-" + version
            kernelFile = "%s/vmlinuz%s" % (cfPath, kernelTag)

            f.write("image=%s\n" % (kernelFile,))
            f.write("\tlabel=%s\n" % (label,))
            f.write("\tread-only\n")

            initrd = self.makeInitrd(kernelTag, instRoot)
            if initrd:
                f.write("\tinitrd=%s/%s\n" % (cfPath, initrd))

            append = "%s" % (self.args.get(),)

            realroot = rootDev.fstabSpec
            if rootIsDevice(realroot):
                f.write("\troot=%s\n" % (realroot,))
            else:
                if len(append) > 0:
                    append = "%s root=%s" % (append, realroot)
                else:
                    append = "root=%s" % (realroot,)

            if len(append) > 0:
                f.write("\tappend=\"%s\"\n" % (append,))
            f.write("\n")

        f.close()
        os.chmod(instRoot + cf, 0600)

        # FIXME: hack to make sure things are written to disk
        import isys
        isys.sync()
        isys.sync()
        isys.sync()

        backup = "%s/backup.b" % (cfPath,)
        sbinargs = ["/sbin/silo", "-f", "-C", cf, "-S", backup]
        if (iutil.getSparcMachine() == "sun4u" or iutil.getSparcMachine() == "sun4v"):
            sbinargs += ["-u"]
        else:
            sbinargs += ["-U"]

        rc = iutil.execWithRedirect(sbinargs[0],
                                    sbinargs[1:],
                                    stdout = "/dev/tty5",
                                    stderr = "/dev/tty5",
                                    root = instRoot)
        if rc:
            return rc

        if (not os.access(instRoot + "/etc/silo.conf", os.R_OK) and
            os.access(instRoot + "/boot/silo.conf", os.R_OK)):
            os.symlink("../boot/silo.conf",
                       instRoot + "/etc/silo.conf")

        return 0

    def setPassword(self, val, isCrypted = 1):
        # silo just handles the password unencrypted
        self.password = val

    def write(self, instRoot, bl, kernelList, chainList,
              defaultDev):
        if len(kernelList) >= 1:
            return self.writeSilo(instRoot, bl, kernelList, chainList,
                                  defaultDev)
        else:
            raise BootyNoKernelWarning

    def __init__(self, anaconda):
        bootloaderInfo.__init__(self, anaconda)
        self.useSiloVal = 1
        self.kernelLocation = "/boot"
        self._configdir = "/etc"
        self._configname = "silo.conf"
