#!/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 os

import nbhelper

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()

            # If the key exists in generated config, warning with the key name
            extra_config = device.generate_extra_config()
            for key in extra_config.keys():
                if key in output_yaml:
                    nbhelper.utils.logger.warning(
                        "Output YAML Key %s was overwritten", key
                    )

            output_yaml.update(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)
