#
# server.py
#

import os, iutil

import yuminstall

from installclass import BaseInstallClass
from kickstart import AnacondaKSScript as Script

from flags import flags
from constants import *
from pykickstart.constants import *
from storage.partspec import *

import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)

import logging
log = logging.getLogger("anaconda")

class Script:
    def __repr__(self):
        str = ("(s: '%s' i: %s c: %d)") % \
            (self.script, self.interp, self.inChroot)
        return string.replace(str, "\n", "|")

    def __init__(self, script, interp = '/bin/sh', inChroot = 1, logfile = None):
        self.script = script
        self.interp = interp
        self.inChroot = inChroot
        self.logfile = logfile

    def run(self, chroot, serial, intf = None):
        import tempfile
        import os.path

        if self.inChroot:
            scriptRoot = chroot
        else:
            scriptRoot = "/"

        (fd, path) = tempfile.mkstemp("", "sme-script-", scriptRoot + "/tmp")

        os.write(fd, self.script)
        os.close(fd)
        os.chmod(path, 0700)

        if self.logfile:
            if self.inChroot:
                messages = "%s/%s" % (scriptRoot, self.logfile)
            else:
                messages = self.logfile

            d = os.path.dirname(messages)
            if not os.path.exists(d):
                os.makedirs(d)
        elif serial:
            messages = "%s.log" % path
        else:
            messages = "/dev/tty3"

        if intf:
            intf.suspend()
        rc = iutil.execWithRedirect(self.interp, ["/tmp/%s" % os.path.basename(path)],
                                    stdin = messages, stdout = messages, stderr = messages,
                                    root = scriptRoot)
        if intf:
            intf.resume()

        if rc != 0:
            log.error("ERROR - Error code %s encountered running a sme script", rc)

        os.unlink(path)
        if serial or self.logfile:
            os.chmod("%s" % messages, 0600)

class InstallClass(BaseInstallClass):
    # make sure the translation data is read from product.img tree
    if os.path.isdir("/tmp/product/locale"):
        import gettext
        gettext.bindtextdomain("comps", localedir="/tmp/product/locale")
        _ = lambda x: gettext.ldgettext("comps", x)
        N_ = lambda x: x

    # name has underscore used for mnemonics, strip if you dont need it
    id = "server"
    name = N_("SME Server")
    _description = N_("The default installation of %s is a basic server install. "
                     "You can optionally select a different set of software "
                     "now.")
    sortPriority = 90000
    hidden = 0

    bootloaderTimeoutDefault = 5
    tasks = [(N_("Basic Server"),
              ["base", "core"]),
             (N_("Minimal"),
              ["core"])]

    def _get_description(self):
        return gettext.ldgettext("comps", self._description) % self._descriptionFields
    description = property(_get_description)

    def postAction(self, anaconda):
        if anaconda.id.getUpgrade():
            w = anaconda.intf.waitWindow(_("Post Upgrade"),
                _("Performing post-upgrade configuration"))
            log.info("Running post-upgrade action script")
            script = Script( "#!/bin/sh\n/sbin/rsyslogd; sleep 2; /sbin/e-smith/signal-event post-upgrade; touch /forcequotacheck\n" )
        else:
            w = anaconda.intf.waitWindow(_("Post Installation"),
                _("Performing post-installation configuration"))
            log.info("Running post-install action script")
            script = Script( "#!/bin/sh\n/sbin/rsyslogd; sleep 2; /sbin/e-smith/signal-event post-install; touch /forcequotacheck\n" )

        script.run(anaconda.rootPath, flags.serial, anaconda.intf)
        if anaconda.intf is not None:
            w.pop()

        BaseInstallClass.postAction(self, anaconda)

    def setSteps(self, anaconda):
        BaseInstallClass.setSteps(self, anaconda)
        anaconda.dispatch.skipStep("welcome")
        #anaconda.dispatch.skipStep("filtertype")
        anaconda.dispatch.skipStep("network")
        anaconda.dispatch.skipStep("accounts")
        anaconda.dispatch.skipStep("partition")
        anaconda.dispatch.skipStep("tasksel")
        anaconda.dispatch.skipStep("firstboot")

    def setDefaultPartitioning(self, storage, platform):
        autorequests = []

        # If user specifies "nolvm", then asVol = False; otherwise, asVol = True
        # If asVol = False below, then LVM won't be used

        asVol_flag = not flags.cmdline.has_key("nolvm")

        # If user specifies "noraid", then useRAID = False; otherwise, useRAID = True
        # If useRAID = False below, then RAID1 won't be used

        if flags.cmdline.has_key("noraid"):
            raidLevel = "none"
        else:
            raidLevel = "1"
            if flags.cmdline.has_key("raid") and flags.cmdline["raid"] in ["none","0","1","5","6"]:
                raidLevel = flags.cmdline["raid"]

        fstype = "ext4"
        if flags.cmdline.has_key("ext3"):
            fstype = "ext3"

        # /boot
        # Manually specify fstype = ext3/ext4 and size = 250 MB
        # (Platform default is fstype ext4 and size = 500 MB)

        autorequests.append(PartSpec(mountpoint="/boot", fstype=fstype, size=250, raidLevel="1",
                            weight=platform.weight(mountpoint="/boot")))

        # /
        # Manually specify fstype = ext3/ext4 and size = 2048 MB, but growable

        autorequests.append(PartSpec(mountpoint="/", fstype=fstype, size=2048, raidLevel=raidLevel,
                            grow=True, asVol=asVol_flag))

        # swap
        # Manually specify fstype = swap and minswap < size < maxswap (growable)

        (minswap, maxswap) = iutil.swapSuggestion()
        autorequests.append(PartSpec(fstype="swap", size=minswap, maxSize=maxswap, raidLevel=raidLevel,
                            grow=True, asVol=asVol_flag))

        storage.autoPartitionRequests = autorequests

    def setInstallData(self, anaconda):
        BaseInstallClass.setInstallData(self, anaconda)
        anaconda.id.security.setSELinux(SELINUX_DISABLED)
        self.setDefaultPartitioning(
                               anaconda.id.storage,
                               anaconda.platform)

    def productMatches(self, oldprod):
        log.info("oldprod %s productName %s" % (oldprod, productName));
        if oldprod is None:
            return False

        if oldprod.startswith(productName):
            return True

        productUpgrades = {
            "SME Server": ("Mitel Networks", "SME Server", "e-smith server", ),
        }

        if productUpgrades.has_key(productName):
            acceptable = productUpgrades[productName]
        else:
            acceptable = ()

        for p in acceptable:
            if oldprod.startswith(p):
                return True

        return False

    def versionMatches(self, oldver):
        log.info("oldver %s productVersion %s" % (oldver, productVersion));
        return True;

    def getBackend(self):
        return yuminstall.YumBackend

    def __init__(self):
        BaseInstallClass.__init__(self)
