#!/usr/bin/env python3

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

# service.py
#

import re
import netaddr

from .utils import logger, AttrDict
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}."


    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 o2 >= 16 and 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
