# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Dynamic Update Support"""

import dns.message
import dns.name
import dns.opcode
import dns.rdata
import dns.rdataclass
import dns.rdataset

class Update(dns.message.Message):
    def __init__(self, zone, rdclass=dns.rdataclass.IN, keyring=None,
                 keyname=None, keyalgorithm=dns.tsig.default_algorithm):
        """Initialize a new DNS Update object.

        @param zone: The zone which is being updated.
        @type zone: A dns.name.Name or string
        @param rdclass: The class of the zone; defaults to dns.rdataclass.IN.
        @type rdclass: An int designating the class, or a string whose value
        is the name of a class.
        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @type keyname: dns.name.Name or string
        @param keyalgorithm: The TSIG algorithm to use; defaults to
        dns.tsig.default_algorithm
        @type keyalgorithm: string
        """
        super(Update, self).__init__()
        self.flags |= dns.opcode.to_flags(dns.opcode.UPDATE)
        if isinstance(zone, (str, unicode)):
            zone = dns.name.from_text(zone)
        self.origin = zone
        if isinstance(rdclass, str):
            rdclass = dns.rdataclass.from_text(rdclass)
        self.zone_rdclass = rdclass
        self.find_rrset(self.question, self.origin, rdclass, dns.rdatatype.SOA,
                        create=True, force_unique=True)
        if not keyring is None:
            self.use_tsig(keyring, keyname, keyalgorithm)

    def _add_rr(self, name, ttl, rd, deleting=None, section=None):
        """Add a single RR to the update section."""

        if section is None:
            section = self.authority
        covers = rd.covers()
        rrset = self.find_rrset(section, name, self.zone_rdclass, rd.rdtype,
                                covers, deleting, True, True)
        rrset.add(rd, ttl)

    def _add(self, replace, section, name, *args):
        """Add records.  The first argument is the replace mode.  If
        false, RRs are added to an existing RRset; if true, the RRset
        is replaced with the specified contents.  The second
        argument is the section to add to.  The third argument
        is always a name.  The other arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string..."""

        if isinstance(name, (str, unicode)):
            name = dns.name.from_text(name, None)
        if isinstance(args[0], dns.rdataset.Rdataset):
            for rds in args:
                if replace:
                    self.delete(name, rds.rdtype)
                for rd in rds:
                    self._add_rr(name, rds.ttl, rd, section=section)
        else:
            args = list(args)
            ttl = int(args.pop(0))
            if isinstance(args[0], dns.rdata.Rdata):
                if replace:
                    self.delete(name, args[0].rdtype)
                for rd in args:
                    self._add_rr(name, ttl, rd, section=section)
            else:
                rdtype = args.pop(0)
                if isinstance(rdtype, str):
                    rdtype = dns.rdatatype.from_text(rdtype)
                if replace:
                    self.delete(name, rdtype)
                for s in args:
                    rd = dns.rdata.from_text(self.zone_rdclass, rdtype, s,
                                             self.origin)
                    self._add_rr(name, ttl, rd, section=section)

    def add(self, name, *args):
        """Add records.  The first argument is always a name.  The other
        arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string..."""
        self._add(False, self.authority, name, *args)

    def delete(self, name, *args):
        """Delete records.  The first argument is always a name.  The other
        arguments can be:

                - I{nothing}

                - rdataset...

                - rdata...

                - rdtype, [string...]"""

        if isinstance(name, (str, unicode)):
            name = dns.name.from_text(name, None)
        if len(args) == 0:
            rrset = self.find_rrset(self.authority, name, dns.rdataclass.ANY,
                                    dns.rdatatype.ANY, dns.rdatatype.NONE,
                                    dns.rdatatype.ANY, True, True)
        elif isinstance(args[0], dns.rdataset.Rdataset):
            for rds in args:
                for rd in rds:
                    self._add_rr(name, 0, rd, dns.rdataclass.NONE)
        else:
            args = list(args)
            if isinstance(args[0], dns.rdata.Rdata):
                for rd in args:
                    self._add_rr(name, 0, rd, dns.rdataclass.NONE)
            else:
                rdtype = args.pop(0)
                if isinstance(rdtype, str):
                    rdtype = dns.rdatatype.from_text(rdtype)
                if len(args) == 0:
                    rrset = self.find_rrset(self.authority, name,
                                            self.zone_rdclass, rdtype,
                                            dns.rdatatype.NONE,
                                            dns.rdataclass.ANY,
                                            True, True)
                else:
                    for s in args:
                        rd = dns.rdata.from_text(self.zone_rdclass, rdtype, s,
                                                 self.origin)
                        self._add_rr(name, 0, rd, dns.rdataclass.NONE)

    def replace(self, name, *args):
        """Replace records.  The first argument is always a name.  The other
        arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string...

        Note that if you want to replace the entire node, you should do
        a delete of the name followed by one or more calls to add."""

        self._add(True, self.authority, name, *args)

    def present(self, name, *args):
        """Require that an owner name (and optionally an rdata type,
        or specific rdataset) exists as a prerequisite to the
        execution of the update.  The first argument is always a name.
        The other arguments can be:

                - rdataset...

                - rdata...

                - rdtype, string..."""

        if isinstance(name, (str, unicode)):
            name = dns.name.from_text(name, None)
        if len(args) == 0:
            rrset = self.find_rrset(self.answer, name,
                                    dns.rdataclass.ANY, dns.rdatatype.ANY,
                                    dns.rdatatype.NONE, None,
                                    True, True)
        elif isinstance(args[0], dns.rdataset.Rdataset) or \
             isinstance(args[0], dns.rdata.Rdata) or \
             len(args) > 1:
            if not isinstance(args[0], dns.rdataset.Rdataset):
                # Add a 0 TTL
                args = list(args)
                args.insert(0, 0)
            self._add(False, self.answer, name, *args)
        else:
            rdtype = args[0]
            if isinstance(rdtype, str):
                rdtype = dns.rdatatype.from_text(rdtype)
            rrset = self.find_rrset(self.answer, name,
                                    dns.rdataclass.ANY, rdtype,
                                    dns.rdatatype.NONE, None,
                                    True, True)

    def absent(self, name, rdtype=None):
        """Require that an owner name (and optionally an rdata type) does
        not exist as a prerequisite to the execution of the update."""

        if isinstance(name, (str, unicode)):
            name = dns.name.from_text(name, None)
        if rdtype is None:
            rrset = self.find_rrset(self.answer, name,
                                    dns.rdataclass.NONE, dns.rdatatype.ANY,
                                    dns.rdatatype.NONE, None,
                                    True, True)
        else:
            if isinstance(rdtype, str):
                rdtype = dns.rdatatype.from_text(rdtype)
            rrset = self.find_rrset(self.answer, name,
                                    dns.rdataclass.NONE, rdtype,
                                    dns.rdatatype.NONE, None,
                                    True, True)

    def to_wire(self, origin=None, max_size=65535):
        """Return a string containing the update in DNS compressed wire
        format.
        @rtype: string"""
        if origin is None:
            origin = self.origin
        return super(Update, self).to_wire(origin, max_size)
