"""
GSO settings, ensuring that the required parameters are set correctly.
"""
import ipaddress
import json
import os
from pydantic import BaseSettings, Field


class GeneralParams(BaseSettings):
    """
    General parameters for a GSO configuration file.
    """
    #: The hostname that GSO is publicly served at, used for building the
    #: callback URL that the provisioning proxy uses.
    public_hostname: str


class InfoBloxParams(BaseSettings):
    """
    Parameters related to InfoBlox.
    """
    scheme: str
    wapi_version: str
    host: str
    username: str
    password: str


class V4NetworkParams(BaseSettings):
    """
    A set of parameters that describe an IPv4 network in InfoBlox.
    """
    containers: list[ipaddress.IPv4Network]
    networks: list[ipaddress.IPv4Network]
    mask: int = Field(None, ge=0, le=32)


class V6NetworkParams(BaseSettings):
    """
    A set of parameters that describe an IPv6 network in InfoBlox.
    """
    containers: list[ipaddress.IPv6Network]
    networks: list[ipaddress.IPv6Network]
    mask: int = Field(None, ge=0, le=128)


class ServiceNetworkParams(BaseSettings):
    """
    Parameters for InfoBlox that describe IPv4 and v6 networks, and the
    corresponding domain name that should be used as a suffix.
    """
    V4: V4NetworkParams
    V6: V6NetworkParams
    domain_name: str


class IPAMParams(BaseSettings):
    """
    A set of parameters related to IPAM.
    """
    INFOBLOX: InfoBloxParams
    LO: ServiceNetworkParams
    TRUNK: ServiceNetworkParams
    GEANT_IP: ServiceNetworkParams


class ProvisioningProxyParams(BaseSettings):
    """
    Parameters for the provisioning proxy.
    """
    scheme: str
    api_base: str
    auth: str  # FIXME: unfinished
    api_version: int


class OSSParams(BaseSettings):
    """
    The set of parameters required for running GSO.
    """
    GENERAL: GeneralParams
    IPAM: IPAMParams
    RESOURCE_MANAGER_API_PREFIX: str
    PROVISIONING_PROXY: ProvisioningProxyParams


def load_oss_params() -> OSSParams:
    """
    look for OSS_PARAMS_FILENAME in the environment and load the parameters
    from that file.
    """
    with open(os.environ['OSS_PARAMS_FILENAME'], encoding='utf-8') as file:
        return OSSParams(**json.loads(file.read()))


if __name__ == '__main__':
    print(load_oss_params())