#!/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.yaml 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.Tenant()

    # use base_config for additional items
    yaml = YAML(typ="rt")
    base_yaml = yaml.load(args.base_config.read())

    dhcpd_interfaces = []

    # TODO
    # dhcpd_if = dhcpd_subnet.dhcpd_interface
    dns_forward_zones = nbhelper.service.dnsFowardZoneConfigGenerator()
    dns_reverse_zones = nbhelper.service.dnsReverseZoneConfigGenerator()
    dhcpd_subnets = nbhelper.service.dhcpSubnetConfigGenerator()

    for device in tenant.get_devices(device_types=["server", "router", "switch"]):
        output_yaml = base_yaml.copy()

        if (
            isinstance(device, nbhelper.Device)
            and device.data.device_role.slug == "router"
        ) or (
            isinstance(device, nbhelper.VirtualMachine)
            and device.data.role.slug == "router"
        ):
            output_yaml["dns_forward_zones"] = dns_forward_zones
            output_yaml["dns_reverse_zones"] = dns_reverse_zones
            output_yaml["dhcpd_subnets"] = dhcpd_subnets
            output_yaml["dhcpd_interfaces"] = list(device.internal_interfaces.keys())
            output_yaml["netprep_nftables"] = device.generate_nftables()
            output_yaml.update(device.generate_extra_config())
            output_yaml = nbhelper.utils.apply_as_router(output_yaml)

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

        with open("inventory/host_vars/%s.yaml" % device.fullname, "w") as f:
            # yaml.compact(seq_seq=False, seq_map=False)
            yaml.dump(output_yaml, f)
