from bundlewrap.metadata import atomic

defaults = {
    'apt': {
        'packages': {
            'postfix': {},
            'python3-dnsq': {
                # handled by pkg_pip
                'installed': False,
            },
        },
    },
    'icinga2_api': {
        'postfix': {
            'services': {
                'POSTFIX PROCESS': {
                    'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_systemd_unit postfix' + ('' if node.os == 'arch' else '@-'),
                },
                'POSTFIX QUEUE': {
                    'command_on_monitored_host': 'sudo /usr/local/share/icinga/plugins/check_postfix_queue -w 20 -c 40 -d 50',
                },
            },
        },
    },
    'pacman': {
        'packages': {
            'postfix': {},
            's-nail': {},
        },
    },
}

if node.has_bundle('postfixadmin'):
    defaults['icinga2_api']['postfix']['services'].update({
        'SMTP CONNECT': {
            'check_command': 'check_smtp',
            'max_check_attempts': '5',
            'retry_interval': '3m',
            'vars.notification.sms': True,
        },
        'SMTP SUBMISSION CONNECT': {
            'check_command': 'check_smtp',
            'max_check_attempts': '5',
            'retry_interval': '3m',
            'vars.notification.sms': True,
            'vars.port': '587',
        },
    })

else:
    defaults['icinga2_api']['postfix']['services'].update({
        'SMTP CONNECT': {
            'command_on_monitored_host': '/usr/lib/nagios/plugins/check_smtp -H localhost',
        },
    })

if node.has_bundle('telegraf'):
    defaults['telegraf'] = {
        'input_plugins': {
            'exec': {
                'postfix': {
                    'commands': ['postfix-telegraf-queue'],
                    'interval': '30s',
                    'data_format': 'influx',
                    'timeout': '5s',
                },
            },
        },
        'sudo_commands': {
            '/usr/sbin/postqueue -j',
        },
    }


@metadata_reactor.provides(
    'letsencrypt/domains',
    'letsencrypt/reload_after',
)
def letsencrypt(metadata):
    if not node.has_bundle('letsencrypt') or not node.has_bundle('postfixadmin'):
        raise DoNotRunAgain

    result = {
        'reload_after': {
            'postfix',
        },
    }

    result['domains'] = {
        metadata.get('postfix/myhostname', metadata.get('hostname')): set(),
    }

    return {
        'letsencrypt': result,
    }


@metadata_reactor.provides(
    'firewall/port_rules/25',
    'firewall/port_rules/465',
    'firewall/port_rules/587',
    'firewall/port_rules/2525',
)
def firewall(metadata):
    if node.has_bundle('postfixadmin'):
        default = {'*'}
    else:
        default = metadata.get('postfix/mynetworks', set())

    rules = {
        '25': atomic(metadata.get('postfix/restrict-to', default)),
        '465': atomic(metadata.get('postfix/restrict-to', default)),
    }

    if node.has_bundle('postfixadmin'):
        rules['587'] = atomic(metadata.get('postfix/restrict-to', default))
        rules['2525'] = atomic(metadata.get('postfix/restrict-to', default))

    return {
        'firewall': {
            'port_rules': rules,
        },
    }


@metadata_reactor.provides(
    'icinga2_api/postfix/services',
)
def icinga2(metadata):
    if metadata.get('postfix/relayhost', ''):
        # The system does not send mail on its own. There is no point in
        # checking it for any listings.
        return {}

    services = {}
    for ip_type in repo.libs.tools.resolve_identifier(repo, node.name).values():
        for ip in ip_type:
            if not ip.is_private:
                services[f'SPAM BLOCKLIST {ip}'] = {
                    'check_command': 'spam_blocklist',
                    'vars.ip': str(ip),
                }

    return {
        'icinga2_api': {
            'postfix': {
                'services': services,
            },
        },
    }