#!/usr/bin/env python3

# SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org>
# SPDX-License-Identifier: Apache-2.0

# service.py

import netaddr

from .container import ServiceInfoContainer


def getIPaddress(addressWithMask):
    return str(netaddr.IPNetwork(addressWithMask).ip)


def dhcpSubnetConfigGenerator():
    dhcpSubnetConfigs = list()

    serviceInfoContainer = ServiceInfoContainer()
    serviceInfoContainer.initialize()

    for domainName, domain in serviceInfoContainer.all():
        subnetConfig = {
            "dns_search": [domainName],
            "dns_servers": [domain["dnsServer"]["address"]],
            "ntp_servers": [domain["ntpServer"]["address"]],
            "tftpd_server": domain["dhcpServer"]["address"],
            "range": domain["dhcprange"][0],
            "subnet": domain["subnet"],
            "routers": domain["router"],
            "hosts": list(),
        }

        for address, host in domain["hosts"].items():
            subnetConfig["hosts"].append(
                {
                    "ip_addr": getIPaddress(address),
                    "mac_addr": host["macaddr"],
                    "name": host["hostname"],
                }
            )

        subnetConfig["hosts"] = sorted(
            subnetConfig["hosts"], key=lambda x: int(x["ip_addr"].split(".")[-1])
        )
        dhcpSubnetConfigs.append(subnetConfig)

    return dhcpSubnetConfigs


def dnsFowardZoneConfigGenerator():
    def getDomainNameByIP(ip_address):
        """
        getDomainNameByIP will return the corresponding domain name of an IP address
        In the ntpServer, dhcpServer, dnsServer we only have the IP addresses of them,
        But we can use the dhcp subnet configuration to find the FQDN
        """
        dhcpSubnetConfigs = dhcpSubnetConfigGenerator()

        for domain in dhcpSubnetConfigs:
            domainName = domain["dns_search"][0]
            for host in domain["hosts"]:
                if ip_address == host["ip_addr"]:
                    return f"{host['name']}.{domainName}."
        return ""

    dnsForwardZoneConfigs = dict()

    serviceInfoContainer = ServiceInfoContainer()
    serviceInfoContainer.initialize()

    for domainName, domain in serviceInfoContainer.all():
        forwardZoneConfig = {
            "cname": dict(),
            "a": dict(),
            "ns": list(),
            "srv": dict(),
            "txt": dict(),
        }

        # Get the services set to this Tenant network
        ntpServer = domain["ntpServer"] or None
        dhcpServer = domain["dhcpServer"] or None
        dnsServer = domain["dnsServer"] or None

        # If service exists, set the FQDN to CNAME records
        if ntpServer:
            forwardZoneConfig["cname"]["ntp"] = getDomainNameByIP(ntpServer["address"])
        if dhcpServer:
            forwardZoneConfig["cname"]["tftp"] = getDomainNameByIP(
                dhcpServer["address"]
            )
        if dnsServer:
            forwardZoneConfig["cname"]["ns"] = getDomainNameByIP(dnsServer["address"])
            forwardZoneConfig["ns"].append(getDomainNameByIP(dnsServer["address"]))

        for address, host in domain["hosts"].items():
            # Add exist IP address into dnsReverseZoneConfigs,
            hostname = host["hostname"]
            forwardZoneConfig["a"][hostname] = address

        for address in netaddr.IPSet(domain["dhcprange"]):
            # If address exists in ServiceInfoContainer's host dictionary,
            # Use the pre-generated hostname as A record's name
            hostname = "dhcp%03d" % address.words[-1]
            forwardZoneConfig["a"][hostname] = str(address)

        dnsForwardZoneConfigs[domainName] = forwardZoneConfig

    return dnsForwardZoneConfigs


def dnsReverseZoneConfigGenerator():
    def canonicalize_rfc1918_prefix(prefix):
        """
        RFC1918 prefixes need to be expanded to their widest canonical range to
        group all reverse lookup domains together for reverse DNS with NSD/Unbound.
        """

        pnet = netaddr.IPNetwork(prefix)
        (o1, o2, o3, o4) = pnet.network.words  # Split ipv4 octets
        cidr_plen = pnet.prefixlen

        if o1 == 10:
            o2 = o3 = o4 = 0
            cidr_plen = 8
        elif (o1 == 172 and 16 <= o2 <= 31) or (o1 == 192 and o2 == 168):
            o3 = o4 = 0
            cidr_plen = 16

        return "%s/%d" % (".".join(map(str, [o1, o2, o3, o4])), cidr_plen)

    serviceInfoContainer = ServiceInfoContainer()
    serviceInfoContainer.initialize()

    # dnsReverseZoneConfigs contains all reverse zone records.
    dnsReverseZoneConfigs = dict()
    widedomain = None

    for domainName, domain in serviceInfoContainer.all():

        # Expand network range to group all tenant domains
        widedomain = widedomain or canonicalize_rfc1918_prefix(domain["subnet"])

        # Create the basic structure of reverse zone config
        # {"10.0.0.0/8": {"ns": list(), "ptr": dict()}}
        dnsReverseZoneConfigs.setdefault(widedomain, dict())
        dnsReverseZoneConfigs[widedomain].setdefault("ns", list())
        dnsReverseZoneConfigs[widedomain].setdefault("ptr", dict())

        # Get the DNS services set to this Tenant network
        dnsServer = domain["dnsServer"]["name"] if domain["dnsServer"] else None

        # If service exists, set the FQDN to CNAME records
        if dnsServer:
            dnsReverseZoneConfigs[widedomain]["ns"].append(f"{domainName}.{dnsServer}.")

        for address, host in domain["hosts"].items():
            # Add exist IP address into dnsReverseZoneConfigs,
            hostname = host["hostname"]
            dnsReverseZoneConfigs[widedomain]["ptr"][
                address
            ] = f"{hostname}.{domainName}."

        for address in netaddr.IPSet(domain["dhcprange"]):
            # Add DHCP range IP address into dnsReverseZoneConfigs,
            # Use the pre-generated hostname as A record's name
            hostname = "dhcp%03d" % address.words[3]
            dnsReverseZoneConfigs[widedomain]["ptr"][
                str(address)
            ] = f"{hostname}.{domainName}."

    dnsReverseZoneConfigs[widedomain]["ptr"] = dict(
        sorted(
            dnsReverseZoneConfigs[widedomain]["ptr"].items(),
            key=lambda x: (int(x[0].split(".")[-2]), int(x[0].split(".")[-1])),
        )
    )

    return dnsReverseZoneConfigs
