#coding:utf-8
import os
import sunhpc
class Command(sunhpc.commands.HostArgumentProcessor,
        sunhpc.commands.report.command):
    """
    Output the DHCP server configuration infomation
    <example cmd='report host dhcpd'>
    Output dhcpd data for host.
    </example>

    <arg type='str' name='host'>
    Specify an node name.
    </arg>
    """
    def makeAttrDictionary(self):
        self.db.execute("""
            select n.id, n.name, att.attr, att.value from nodes n, attributes att
            where att.node = n.id order by n.id""")
        self.attrdict = {}
        for row in self.db.fetchall():
            key = "%d-%s" % (row[0], row[2])
            self.attrdict[key] = row[3]

    def printHost(self, name, hostname, mac, ip, filename, nextserver):
        self.addOutput('', '\t\thost %s {' % name)
        if mac:
            self.addOutput('', '\t\t\thardware ethernet %s;' % mac)

        self.addOutput('', '\t\t\toption host-name "%s";' % hostname)
        self.addOutput('', '\t\t\tfixed-address %s;' % ip)

        if filename:
            self.addOutput('','\t\t\tfilename "%s";' % filename)
        if nextserver:
            self.addOutput('','\t\t\tnext-server %s;' % nextserver)
        self.addOutput('', '\t\t}')

    def printOptions(self, prefix):

        self.addOutput('', '%soption routers %s;' %
            (prefix, self.db.getHostAttr('localhost', 'Kickstart_PrivateGateway')))

        self.addOutput('', '%soption subnet-mask %s;' %
            (prefix, self.db.getHostAttr('localhost', 'Kickstart_PrivateNetmask')))

        self.addOutput('', '%soption domain-name "%s";' %
            (prefix, self.db.getHostAttr('localhost', 'Kickstart_PrivateDNSDomain')))

        self.addOutput('', '%soption domain-name-servers %s;' %
            (prefix, self.db.getHostAttr('localhost', 'Kickstart_PrivateDNSServer')))

        self.addOutput('', '%soption interface-mtu %s;' %
            (prefix, self.db.getHostAttr('localhost', 'Kickstart_PrivateMTU')))

    def writeDHCPConf(self, host):

        ip = self.db.getHostAttr('localhost', 'Kickstart_PrivateAddress')
        dm = self.db.getHostAttr('localhost', 'Kickstart_PrivateDNSDomain')
        nw = self.db.getHostAttr('localhost', 'Kickstart_PrivateNetwork')
        nm = self.db.getHostAttr('localhost', 'Kickstart_PrivateNetmask')
        dl = self.db.getHostAttr('localhost', 'Kickstart_DefaultLeaseTime')
        ml = self.db.getHostAttr('localhost', 'Kickstart_MaxLeaseTime')

        if not dl: dl = '1200'
        if not ml: ml = '1200'

        #self.addOutput('', '<file name="/etc/dhcp/dhcpd.conf">')
        self.addOutput('', 'ddns-update-style none;')
        self.addOutput('', 'subnet %s netmask %s {' % (nw, nm))
        self.addOutput('', '\tdefault-lease-time %s;' % dl)
        self.addOutput('', '\tmax-lease-time %s;' % ml)

        self.printOptions('\t')
        self.addOutput('', '\tgroup "%s" {' % dm)

        currnode = 0
        self.makeAttrDictionary()
        self.db.execute("""
            SELECT n.id,n.name,n.rack,n.rank,net.device,net.mac,net.ip,sub.name 
            FROM nodes n INNER JOIN networks net 
            ON net.node=n.id, subnets sub WHERE net.subnet=sub.id 
            AND sub.name="private" 
            UNION
            SELECT n.id,n.name,n.rack,n.rank,net.device,net.mac,
            net.ip, NULL FROM nodes n INNER JOIN networks net 
            ON net.node=n.id where net.subnet IS NULL
            ORDER BY 1,7 DESC""")

        #
        # add exclude mac address from /etc/dhcpd/ehost.conf get.
        # ,e.g. hiwifi 00:00:00:00:00 
        exthost = []
        extfile = '/etc/dhcp/ehost.conf'
        if os.path.exists(extfile):
            with open(extfile, 'r') as f:
                for i in f.readlines():
                    if i.startswith('#'):
                        continue
                    tmp = i.split()
                    tmp.insert(0, 0)
                    tmp.insert(2, 0)
                    tmp.insert(3, 'ext0')
                    tmp.insert(4, 0)
                    tmp.insert(6, '255.255.255.255')
                    tmp.insert(7, 'private')
                    exthost.append(tmp)

        for row in self.db.fetchall() + exthost:
            node        = sunhpc.core.utils.Struct()
            node.id     = row[0]
            node.name   = row[1]
            node.rack   = row[2]
            netdevice   = row[3]
            node.rank   = row[4]
            node.mac    = row[5]
            node.ip     = row[6]
            netname     = row[7]
            hostname    = node.name

            if currnode != node.id:
                currnode = node.id
                unassignedidx = 0

                kickstartable = self.attrdict.get('%d-kickstartable' % node.id)
                if kickstartable:
                    kickstartable = self.str2bool(kickstartable)
                else:
                    kickstartable = False

                if not kickstartable:
                    nextserver = None
                    filename   = None

                if kickstartable:
                    filename   = self.attrdict.get('%d-dhcp_filename' % node.id)
                    nextserver = self.attrdict.get('%d-dhcp_nextserver' % node.id)

            if netname == "private":
                privateIP = node.ip

            if netname is None and node.ip is None:
                node.ip = privateIP

            if node.name is None or node.mac is None or node.ip is None or len(node.mac) > 20:
                continue

            try:
                node.name = node.name + '-' + netdevice.replace(':', '_')
            except:
                pass
            self.printHost(node.name, hostname, node.mac, node.ip, filename, nextserver)

        self.addOutput('', '\t}')
        self.addOutput('', '}')
        #self.addOutput('', '</file>')

    def run(self, params, args):

        if len(args) > 1:
            self.msg('Cannot supply more than one host name', 'a')

        if len(args) == 0:
            args = [ os.uname()[1] ]

        hosts = self.getHostnames(args)
        self.beginOutput()
        self.writeDHCPConf(hosts)
        self.endOutput(padChar='')

RollName = "base"
