from ipaddress import ip_interface
from base64 import b64decode


@metadata_reactor.provides(
    'ssh/allow_users',
)
def users(metadata):
    return {
        'ssh': {
            'allow_users': set(
                name
                    for name, conf in metadata.get('users').items()
                    if conf.get('authorized_keys', []) or conf.get('authorized_users', [])
            ),
        },
    }


@metadata_reactor.provides(
    'ssh/host_key',
)
def host_key(metadata):
    private, public = repo.libs.ssh.generate_ed25519_key_pair(
        b64decode(str(repo.vault.random_bytes_as_base64_for(f"HostKey {metadata.get('id')}", length=32)))
    )

    return {
        'ssh': {
            'host_key': {
                'private': private + '\n',
                'public': public + f' root@{node.name}',
            }
        },
    }


@metadata_reactor.provides(
    'ssh/hostnames',
)
def hostnames(metadata):
    ips = set()

    for network in node.metadata.get('network').values():
        if network.get('ipv4', None):
            ips.add(str(ip_interface(network['ipv4']).ip))
        if network.get('ipv6', None):
            ips.add(str(ip_interface(network['ipv6']).ip))

    domains = {
        domain
            for domain, records in node.metadata.get('dns').items()
            for type, values in records.items()
            if type in {'A', 'AAAA'}
            and set(values) & ips
    }

    return {
        'ssh': {
            'hostnames': {
                node.hostname,
                *ips,
                *domains,
            }
        },
    }