#!/usr/bin/env python3

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

# edgeconfig.py
# Given a yaml config file (same as ansible inventory for a site), create a
# YAML file consumable by ansible as variables that configures the managmeent
# node for that site

from __future__ import absolute_import

import argparse
import nbhelper
import os

from ruamel import yaml

# main function that calls other functions
if __name__ == "__main__":

    # this is passed to argparse, key is option name, rest is kwargs
    extra_args = {
        "base_config": {
            "default": os.path.join(
                os.path.dirname(os.path.realpath(__file__)), "base_edgeconfig.yaml"
            ),
            "nargs": "?",
            "type": argparse.FileType("r"),
            "help": "Config (optional, default: base_edgeconfig.yaml)",
        },
    }

    args = nbhelper.initialize(extra_args)
    tenant = nbhelper.NBTenant()

    # use base_config for additional items
    base_yaml = yaml.safe_load(args.base_config.read())

    dhcpd_subnets = []
    dhcpd_interfaces = []

    # reverse zones aggregate across RFC1918 IP prefix
    dns_reverse_zones = nbhelper.NBDNSReverseZones()
    for prefix in tenant.get_prefixes().values():

        nbhelper.NBDNSForwardZone.get_fwd_zone(prefix)
        dns_reverse_zones.add_prefix(prefix)
        dhcpd_subnet = nbhelper.NBDHCPSubnet(prefix)
        dhcpd_if = dhcpd_subnet.dhcpd_interface

        if dhcpd_if and dhcpd_if not in dhcpd_interfaces:
            dhcpd_interfaces.append(dhcpd_if)

        dhcpd_subnets.append(dhcpd_subnet)

    for device in tenant.get_devices():
        output_yaml = base_yaml.copy()

        if (
            isinstance(device, nbhelper.NBDevice)
            and device.data.device_role.slug == "router"
        ) or (
            isinstance(device, nbhelper.NBVirtualMachine)
            and device.data.role.slug == "router"
        ):
            output_yaml["dns_forward_zones"] = nbhelper.NBDNSForwardZone.all_fwd_zones()
            output_yaml["dns_reverse_zones"] = dns_reverse_zones
            output_yaml["dhcpd_subnets"] = dhcpd_subnets
            output_yaml["dhcpd_interfaces"] = dhcpd_interfaces
            output_yaml["netprep_nftables"] = device.generate_nftables()
            output_yaml.update(device.generate_extra_config())

        output_yaml["netprep_netplan"] = device.generate_netplan()

        with open("inventory/host_vars/%s.yaml" % device.name, "w") as f:
            f.write(yaml.safe_dump(output_yaml, indent=2))
