from ipaddress import ip_address, ip_network

defaults = {
    'apt': {
        'packages': {
            'kea-dhcp4-server': {},
        },
    },
    'kea-dhcp-server': {
        'config': {
            'authoritative': True,
            'rebind-timer': 450,
            'renew-timer': 300,
            'valid-lifetime': 600,
            'expired-leases-processing': {
                'max-reclaim-leases': 0,
                'max-reclaim-time': 0,
            },
            'lease-database': {
                'lfc-interval': 3600,
                'name': '/var/lib/kea/kea-leases4.csv',
                'persist': True,
                'type': 'memfile',
            },
        },
    },
}


@metadata_reactor.provides(
    'kea-dhcp-server/fixed_allocations',
)
def get_static_allocations(metadata):
    result = {}
    mapping = {}

    for iface, config in metadata.get('kea-dhcp-server/subnets', {}).items():
        result[iface] = {}
        mapping[iface] = ip_network(config['subnet'])

    for rnode in repo.nodes:
        if (
            rnode.metadata.get('location', '') != metadata.get('location', '')
            or rnode == node
        ):
            continue

        for iface_name, iface_config in rnode.metadata.get('interfaces', {}).items():
            if iface_config.get('dhcp', False) and iface_config.get('mac'):
                for ip in iface_config.get('ips', set()):
                    ipaddr = ip_address(ip)

                    for kea_iface, kea_subnet in mapping.items():
                        if ipaddr in kea_subnet:
                            result[kea_iface][f'{rnode.name}_{iface_name}'] = {
                                'ip': ip,
                                'mac': iface_config['mac'],
                            }
                            break

    return {
        'kea-dhcp-server': {
            'fixed_allocations': result,
        }
    }


@metadata_reactor.provides(
    'nftables/input/10-kea-dhcp-server',
)
def nftables(metadata):
    rules = set()
    for iface in node.metadata.get('kea-dhcp-server/subnets', {}):
        rules.add(f'udp dport {{ 67, 68 }} iifname {iface} accept')

    return {
        'nftables': {
            'input': {
                # can't use port_rules here, because we're generating interface based rules.
                '10-kea-dhcp-server': sorted(rules),
            },
        }
    }
