#!/usr/bin/env python3

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

# tenant.py
# The tenant abstract object of Netbox Object - Tenant

import sys

from .utils import logger
from .device import Device, VirtualMachine
from .network import Prefix


class Tenant:
    def __init__(self):

        from .utils import netboxapi, netbox_config

        self.nbapi = netboxapi
        self.name = netbox_config["tenant_name"]
        self.name_segments = netbox_config.get("prefix_segments", 1)

        self.tenant = self.nbapi.tenancy.tenants.get(name=self.name)

        # Tenant only keep the resources which owns by it
        self.devices = list()
        self.vms = list()
        self.prefixes = dict()

        # Get the Device and Virtual Machines from Netbox API
        for device_data in self.nbapi.dcim.devices.filter(tenant=self.tenant.slug):
            device = Device(device_data)
            device.tenant = self
            self.devices.append(device)

        for vm_data in self.nbapi.virtualization.virtual_machines.filter(
            tenant=self.tenant.slug
        ):
            vm = VirtualMachine(vm_data)
            vm.tenant = self
            self.vms.append(vm)

        vrf = self.nbapi.ipam.vrfs.get(tenant=self.tenant.slug)
        for prefix_data in self.nbapi.ipam.prefixes.filter(vrf_id=vrf.id):
            prefix = Prefix(prefix_data, self.name_segments)
            if prefix_data.description:
                self.prefixes[prefix_data.prefix] = prefix

    def get_prefixes(self):
        """Get the IP Prefixes owns by current tenant"""

        return self.prefixes

    def get_device_by_name(self, name):
        """
        Find the device or VM which belongs to this Tenant,
        If the name wasn't specified, return the management server
        """

        for machine in self.devices + self.vms:
            if (name and machine.name == name) or machine.data["device_role"][
                "name"
            ] == "Router":
                return machine

        ret_msg = (
            "The name '%s' wasn't found in this tenant, "
            + "or can't found any Router in this tenant"
        )

        logger.error(ret_msg, name)
        sys.exit(1)

    def get_devices(self, device_types=None):
        """
        Get all devices (Router + Server) belong to this Tenant
        """
        if not device_types:
            device_types = ["server", "router"]

        if not device_types:
            return self.devices + self.vms

        ret = []

        for machine in self.devices:
            if machine.data.device_role.slug in device_types:
                ret.append(machine)

        for vm in self.vms:
            if vm.data.role.slug in device_types:
                ret.append(vm)

        return ret
